laddr DialTimeout <> DialTCP

264 views
Skip to first unread message

Paul van Brouwershaven

unread,
Sep 7, 2012, 4:39:33 AM9/7/12
to golan...@googlegroups.com
Hi,

I implemented DialTimeout on a TLS connection and trying to define my source (laddr) address. In previous versions of Go this was possible with the laddr option in the Dial command, now this option is only available in DialTCP but that function does not have a timeout option.

Any ideas how I can make a TLS connection from a defined laddr with a timeout?

    // Configure a timeout of 15 seconds
    ipConn, errDial := net.DialTimeout("tcp", "www.google.com:443", 15*time.Second)
    config := tls.Config{ServerName: "www.google.com"}
    conn := tls.Client(ipConn, &config)
    defer conn.Close()
    
    // TLS Handshake
    errHandshake := conn.Handshake()

Thanks,

Paul

Jingcheng Zhang

unread,
Sep 7, 2012, 4:45:25 AM9/7/12
to Paul van Brouwershaven, golan...@googlegroups.com
You can write it by yourself. Here is my code:

func TcpDial(localAddress string, remoteAddress string, timeout
time.Duration) (*net.TCPConn, error) {
timer := time.NewTimer(timeout)
defer timer.Stop()

type Result struct {
*net.TCPConn
error
}
channel := make(chan *Result, 1)
go func() {
var localAddr, remoteAddr *net.TCPAddr
var err error
var tcpConn *net.TCPConn

if localAddress != "" {
localAddr, err = net.ResolveTCPAddr("tcp", localAddress)
if err != nil {
goto finished
}
}
remoteAddr, err = net.ResolveTCPAddr("tcp", remoteAddress)
if err != nil {
goto finished
}
tcpConn, err = net.DialTCP("tcp", localAddr, remoteAddr)
if err != nil {
goto finished
}
finished:
channel <- &Result{TCPConn: tcpConn, error: err}
}()
select {
case <-timer.C:
return nil, errors.New("connect timeout")
case result := <-channel:
if result.error != nil {
return nil, result.error
}
return result.TCPConn, nil
}
panic("unreachable")
--
Best regards,
Jingcheng Zhang
Beijing, P.R.China

Paul van Brouwershaven

unread,
Sep 7, 2012, 5:08:27 AM9/7/12
to golan...@googlegroups.com, Paul van Brouwershaven
Thanks, you code looks good, this would be a simple solution.

I see your code looks a like the original DialTimeout where the following comment is listed:
   121		// TODO(bradfitz): the timeout should be pushed down into the
   122		// net package's event loop, so on timeout to dead hosts we
   123		// don't have a goroutine sticking around for the default of
   124		// ~3 minutes.
So this basically means that the goroutine keeps running and the TCP session keeps open. Is there a way to kill the goroutine and linked TCP session?

Paul van Brouwershaven

unread,
Sep 7, 2012, 5:56:43 AM9/7/12
to golan...@googlegroups.com, Paul van Brouwershaven
I found issue 2631 that is mentioning this comment.

It looks like the inefficiency in the handling timeouts is not high on the priority list (Priority-Later).

Jingcheng Zhang

unread,
Sep 7, 2012, 6:02:37 AM9/7/12
to Paul van Brouwershaven, brad...@golang.org, golan...@googlegroups.com
On Fri, Sep 7, 2012 at 5:08 PM, Paul van Brouwershaven
<pa...@vanbrouwershaven.com> wrote:
> I see your code looks a like the original DialTimeout where the following
> comment is listed:

Yeah, I "steal" the idea from Brad's DialTimeout() implementation :p

>
> 121 // TODO(bradfitz): the timeout should be pushed down into the
> 122 // net package's event loop, so on timeout to dead hosts we
> 123 // don't have a goroutine sticking around for the default of
> 124 // ~3 minutes.
>
> So this basically means that the goroutine keeps running and the TCP session
> keeps open. Is there a way to kill the goroutine and linked TCP session?

I'm worrying about this too. Maybe Brad will have an idea :)

Paul van Brouwershaven

unread,
Sep 7, 2012, 6:27:14 AM9/7/12
to golan...@googlegroups.com, Paul van Brouwershaven, brad...@golang.org
It's not only worrying me. I have crashed several routers because to-many open sessions.
Reply all
Reply to author
Forward
0 new messages