Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

net: LookupPort translates negative numbers into valid port numbers on Windows without error. #13447

Closed
ChrisHines opened this issue Dec 1, 2015 · 4 comments

Comments

@ChrisHines
Copy link
Contributor

OS: Windows 7 Professional, SP1.
Go: go1.5.1 windows/amd64

The following program prints 65527 on Windows, but panics on Linux.

package main

import (
    "fmt"
    "net"
)

func main() {
    port, err := net.LookupPort("tcp", "-9")
    if err != nil {
        panic(err)
    }
    fmt.Println(port)
}

Also "-2000000000" returns 27648 and "-4294967295" or numerically smaller returns 1.

@bradfitz
Copy link
Contributor

bradfitz commented Dec 1, 2015

/cc @alexbrainman

I guess this is the newLookupPort path?

func newLookupPort(network, service string) (int, error) {
        acquireThread()
        defer releaseThread()
        var stype int32
        switch network {
        case "tcp4", "tcp6":
                stype = syscall.SOCK_STREAM
        case "udp4", "udp6":
                stype = syscall.SOCK_DGRAM
        }
        hints := syscall.AddrinfoW{
                Family:   syscall.AF_UNSPEC,
                Socktype: stype,
                Protocol: syscall.IPPROTO_IP,
        }
        var result *syscall.AddrinfoW
        e := syscall.GetAddrInfoW(nil, syscall.StringToUTF16Ptr(service), &hints, &result)
        if e != nil {
                return 0, &DNSError{Err: os.NewSyscallError("getaddrinfow", e).Error(), Name: network + "/" + service}
        }
        defer syscall.FreeAddrInfoW(result)
        if result == nil {
                return 0, &DNSError{Err: syscall.EINVAL.Error(), Name: network + "/" + service}
        }
        addr := unsafe.Pointer(result.Addr)
        switch result.Family {
        case syscall.AF_INET:
                a := (*syscall.RawSockaddrInet4)(addr)
                return int(syscall.Ntohs(a.Port)), nil
        case syscall.AF_INET6:
                a := (*syscall.RawSockaddrInet6)(addr)
                return int(syscall.Ntohs(a.Port)), nil
        }
        return 0, &DNSError{Err: syscall.EINVAL.Error(), Name: network + "/" + service}
}

@alexbrainman
Copy link
Member

Let me play with this a little bit.

Alex

@alexbrainman
Copy link
Member

@ChrisHines your program prinsts:

panic: invalid port -9

goroutine 1 [running]:
main.main()
        /root/src/t/main.go:11 +0x9b

on my windows 7 amd64 (as expected). Mind you, I use current Go tip. We also have TestLookupPort in net package that checks that net.LookupPort("tcp", "-1") fails. Can you run that test to see if it PASSes? You can add your values to the test to see what is going on. You can also debug this yourself (since it is broken for you). Just add fmt.Printf or similar everywhere in net as you descend into net.LookupPort call. Please let us know how you went. Thank you.

Alex

@ChrisHines
Copy link
Contributor Author

@alexbrainman This issue was fixed by b50b21d.

@golang golang locked and limited conversation to collaborators Dec 1, 2016
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants