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: Dialer.Dial fails with "An invalid argument was supplied." on windows #5355

Closed
alexbrainman opened this issue Apr 26, 2013 · 11 comments

Comments

Projects
None yet
5 participants
@alexbrainman
Copy link
Member

commented Apr 26, 2013

This program 

package main

import (
    "log"
    "net"
    "time"
)

func main() {
    addr, err := net.ResolveTCPAddr("tcp4", "127.0.0.1:0")
    if err != nil {
        log.Fatalf("ResolveTCPAddr failed: %v", err)
    }
    d := &net.Dialer{
        LocalAddr: addr,
        Timeout:   time.Second,
    }
    _, err = d.Dial("tcp4", "127.0.0.1:80")
    if err != nil {
        log.Fatalf("Dial failed: %v", err)
    }

}

fails with "An invalid argument was supplied." error message. The error is
because syscall.Bind is called twice on the socket. First time in sock_posix.go and then
fd_windows.go. The two parts should arrange to have it done only once.

Reported at https://groups.google.com/d/topic/golang-nuts/B4Ah9LYOVhU/discussion.

Alex
@mikioh

This comment has been minimized.

Copy link
Contributor

commented Apr 26, 2013

Comment 1:

Ah, I've never imagined that netFD.connect in fd_windows.go
calls not only Connect/ConnectEx but Bind. Hm, ConnectEx
requires an unnamed/unbound socket, oh-oh.
I will follow whatever you do.
FWIW I'm now preparing a CL for go 1.2 that does refactor 
posix socket stuff especially btw domains IP and Unix, 
dialers and listeners and datagrams and streams to introduce
runtime-integrated poller stuff on BSD variants.
https://golang.org/cl/8726051/
Please let me know if you find some more clear way that
accommodates netFD to tons of socket control knobs, thx.
@alexbrainman

This comment has been minimized.

Copy link
Member Author

commented Apr 26, 2013

Comment 2:

mikio,
ConnectEx requires a locally bound socket. All our outgoing sockets are unbound, so I
put Bind right before I do ConnectEx. That is, until I discovered net.Dialer, which
binds its socket. I am not sure what is correct approach is - where should the
syscall.Bind be called from. So, if you would suggest a good plan, I will make changes.
Alternatively, please, send change yourself, if you like. Thank you.
Alex
@alexbrainman

This comment has been minimized.

Copy link
Member Author

commented Apr 26, 2013

Comment 3:

As to your forthcoming net changes, I would like to make some changes too:
https://golang.org/cl/8670044/. And there will be more to remove memory
allocations during net io. I hope we are not stepping on each other toes.
Alex
@mikioh

This comment has been minimized.

Copy link
Contributor

commented Apr 26, 2013

Comment 4:

Yup, the conflict pattern would be...
- someone tweaks posix stuff
- it breaks windows build (because someone has no windows stuff)
- another one fixes windows build
So, after you; please proceed your runtime poller on windows CL first. :)
@mikioh

This comment has been minimized.

Copy link
Contributor

commented Apr 26, 2013

Comment 5:

Labels changed: added go1.1.

@bradfitz

This comment has been minimized.

Copy link
Member

commented Apr 26, 2013

Comment 6:

Windows would break less if we had more tests. :(  I probably should've added more with
net.Dialer, but I thought it was just a thin shell around existing net APIs.
Did this start breaking with net.Dialer, or has this always been broken with even
net.ResolveTCPAddr + net.DialTCP?
@alexbrainman

This comment has been minimized.

Copy link
Member Author

commented Apr 27, 2013

Comment 7:

I think net.Dialer is broken, while net.Dial works. One supplies local address when
creating socket, while other supplies nil. That goes to different code path, one calls
syscall.Bind explicitly, while the other expect connect to do all the binding. Windows
syscall.ConnextEx needs syscall.Bind to be called explicitly.
I will add test with net.Dialer. That should cover us.
Alex
@alexbrainman

This comment has been minimized.

Copy link
Member Author

commented Apr 27, 2013

Comment 8:

https://golang.org/cl/8966046/

Status changed to Started.

@alexbrainman

This comment has been minimized.

Copy link
Member Author

commented May 1, 2013

Comment 9:

This issue was closed by revision ca6b1f3.

Status changed to Fixed.

@gopherbot

This comment has been minimized.

Copy link

commented Jul 25, 2013

Comment 10 by jleimon:

All,
Please see my trouble report below:
System:
  Go Version:
    go version devel +bea6199b09ea Tue Apr 30 17:47:39 2013 -0700 windows/386
  Operating System:
    Windows Version 6.1.7601
Trouble Description:
  net.Dial("ip", ...) does not work, whereas net.Dial("tcp",...) does work. I've attached a set of unit tests, the output of which is included below.
Test Output:
PS C:\WORKSTATION\WORKSPACE\go_net_test> .\run.bat
C:\WORKSTATION\WORKSPACE\go_net_test>echo off
TEST:  net.Dial("ip4:1", "127.0.0.1")  ... FAIL
  dial ip4 127.0.0.1: ConnectEx ip4: An invalid argument was supplied.
panic: dial ip4 127.0.0.1: ConnectEx ip4: An invalid argument was supplied.
goroutine 1 [running]:
main.main()
        C:/WORKSTATION/WORKSPACE/go_net_test/test_dial_ip4/test_dial_ip4.go:14 +0x109
goroutine 2 [runnable]:
goroutine 3 [runnable]:
net.(*resultSrv).Run(0x122d0188)
        C:/go/src/pkg/net/fd_windows.go:143
created by net.startServer
        C:/go/src/pkg/net/fd_windows.go:286 +0xde
TEST:  net.Dial("ip6:1", "::1")  ... FAIL
  dial ip6 ::1: ConnectEx ip6: An invalid argument was supplied.
panic: dial ip6 ::1: ConnectEx ip6: An invalid argument was supplied.
goroutine 1 [running]:
main.main()
        C:/WORKSTATION/WORKSPACE/go_net_test/test_dial_ip6/test_dial_ip6.go:14 +0x109
goroutine 2 [runnable]:
goroutine 3 [runnable]:
net.(*resultSrv).Run(0x12330190)
        C:/go/src/pkg/net/fd_windows.go:143
created by net.startServer
        C:/go/src/pkg/net/fd_windows.go:286 +0xde
TEST:  net.Dial("ip:1", "127.0.0.1")  ... FAIL
  dial ip 127.0.0.1: ConnectEx ip: An invalid argument was supplied.
panic: dial ip 127.0.0.1: ConnectEx ip: An invalid argument was supplied.
goroutine 1 [running]:
main.main()
        C:/WORKSTATION/WORKSPACE/go_net_test/test_dial_ip_0/test_dial_ip_0.go:14 +0x109
goroutine 2 [runnable]:
goroutine 3 [runnable]:
net.(*resultSrv).Run(0x12230188)
        C:/go/src/pkg/net/fd_windows.go:143
created by net.startServer
        C:/go/src/pkg/net/fd_windows.go:286 +0xde
TEST:  net.Dial("ip:1", "::1")  ... FAIL
  dial ip ::1: ConnectEx ip: An invalid argument was supplied.
panic: dial ip ::1: ConnectEx ip: An invalid argument was supplied.
goroutine 1 [running]:
main.main()
        C:/WORKSTATION/WORKSPACE/go_net_test/test_dial_ip_1/test_dial_ip_1.go:14 +0x109
goroutine 2 [runnable]:
goroutine 3 [runnable]:
net.(*resultSrv).Run(0x12230190)
        C:/go/src/pkg/net/fd_windows.go:143
created by net.startServer
        C:/go/src/pkg/net/fd_windows.go:286 +0xde
TEST:  net.Dial("tcp4", "google.com:80")  ... PASS
TEST:  net.Dial("tcp4", "google.com:http")  ... PASS
TEST:  net.Dial("tcp", "google.com:80")  ... PASS
TEST:  net.Dial("tcp", "google.com:http")  ... PASS
PS C:\WORKSTATION\WORKSPACE\go_net_test>
Notes:
  I have traced the go code to a call to oi.Submit (ConnectEx) that is failing, but I'm not sure why. (See below)
Call Stack for  Dial(network, address string)
  ----> Dial(network, address string)
    ----> resolveAndDial(network, address, d.LocalAddr, d.deadline())
      | 
      | 
      |   X X X X  NOT CALLED  X X X X
      ----> resolveAndDialChannel(net, addr, localAddr, deadline)  
      |   X X X X  NOT CALLED  X X X X
      | 
      | 
      ----> resolveAddr("dial", net, addr, deadline)
      ----> dial(net, addr, localAddr, ra, deadline)
        ----> dialIP(net, la, ra, deadline) [iprawsock_posix.go]
          ----> internetSocket(net, laddr.toAddr(), raddr.toAddr(), deadline, syscall.SOCK_RAW, proto, "dial", sockaddrToIP) [ipsock_posix.go]
            ----> socket(net, family, sotype, proto, ipv6only, la, ra, deadline, toAddr) [sock_posix.go]
              ----> fd.connect(ulsa, ursa) [fd_windows.go]
                ----> iosrv.ExecIO(&o, fd.wdeadline.value())  [fd_windows.go]
                  ----> oi.Submit() [fd_windows.go] (ConnectEx)

Attachments:

  1. go_net_test.zip (4302 bytes)
@alexbrainman

This comment has been minimized.

Copy link
Member Author

commented Jul 25, 2013

Comment 11:

jleimon,
Please create new issue at https://code.google.com/p/go/issues/entry. Fill in the new
issue form as requested. Please, provide a SMALL program we can run to reproduce your
issue.
Thank you.
Alex

@rsc rsc added this to the Go1.1 milestone Apr 14, 2015

@rsc rsc removed the go1.1 label Apr 14, 2015

@golang golang locked and limited conversation to collaborators Jun 24, 2016

This issue was closed.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
You can’t perform that action at this time.