2010-06-21 20:52:30 -06:00
|
|
|
// Copyright 2010 The Go Authors. All rights reserved.
|
|
|
|
// Use of this source code is governed by a BSD-style
|
|
|
|
// license that can be found in the LICENSE file.
|
|
|
|
|
|
|
|
package net
|
|
|
|
|
net: add DialOpt, the extensible Dial w/ options dialer
Add DialOpt. So we have:
func Dial(net, addr string) (Conn, error)
func DialTimeout(net, addr string, timeout time.Duration) (Conn, error)
func DialOpt(addr string, opts ...DialOption) (Conn, error)
DialTimeout (and Dial) are regrettable in retrospect. Maybe
in a future Go we'll be back down to one Dial, with DialOpt
becoming Dial.
DialOpt looks like:
c, err := net.DialOpt("google.com:80") // tcp is default
c, err := net.DialOpt("google.com:80", net.Timeout(30 * time.Second))
c, err := net.DialOpt("google.com:80", net.TCPFastOpen())
c, err := net.DialOpt("google.com:80", net.LocalAddr(..))
c, err := net.DialOpt("google.com:53", net.Network("udp6"))
And then: (clustered in godoc)
type DialOption interface { /* private only */ }
func Deadline(time.Time) DialOption
func LocalAddr(Addr) DialOption
func Network(string) DialOption
func TCPFastOpen() DialOption
func Timeout(time.Duration) DialOption
I'm pretty confident we could add Happy Eyeballs to this too.
Fixes #3097
Update #3610
Update #4842
R=golang-dev, r, dave, minux.ma, rsc
CC=golang-dev
https://golang.org/cl/7365049
2013-02-27 12:59:36 -07:00
|
|
|
import (
|
|
|
|
"errors"
|
|
|
|
"time"
|
|
|
|
)
|
|
|
|
|
|
|
|
// A DialOption modifies a DialOpt call.
|
|
|
|
type DialOption interface {
|
2013-03-09 19:14:00 -07:00
|
|
|
setDialOpt(*dialOpts)
|
|
|
|
}
|
|
|
|
|
|
|
|
var noLocalAddr Addr // nil
|
|
|
|
|
|
|
|
// dialOpts holds all the dial options, populated by a DialOption's
|
|
|
|
// setDialOpt.
|
|
|
|
//
|
|
|
|
// All fields may be their zero value.
|
|
|
|
type dialOpts struct {
|
|
|
|
deadline time.Time
|
|
|
|
localAddr Addr
|
|
|
|
network string // if empty, "tcp"
|
|
|
|
deferredConnect bool
|
|
|
|
}
|
|
|
|
|
|
|
|
func (o *dialOpts) net() string {
|
|
|
|
if o.network == "" {
|
|
|
|
return "tcp"
|
|
|
|
}
|
|
|
|
return o.network
|
net: add DialOpt, the extensible Dial w/ options dialer
Add DialOpt. So we have:
func Dial(net, addr string) (Conn, error)
func DialTimeout(net, addr string, timeout time.Duration) (Conn, error)
func DialOpt(addr string, opts ...DialOption) (Conn, error)
DialTimeout (and Dial) are regrettable in retrospect. Maybe
in a future Go we'll be back down to one Dial, with DialOpt
becoming Dial.
DialOpt looks like:
c, err := net.DialOpt("google.com:80") // tcp is default
c, err := net.DialOpt("google.com:80", net.Timeout(30 * time.Second))
c, err := net.DialOpt("google.com:80", net.TCPFastOpen())
c, err := net.DialOpt("google.com:80", net.LocalAddr(..))
c, err := net.DialOpt("google.com:53", net.Network("udp6"))
And then: (clustered in godoc)
type DialOption interface { /* private only */ }
func Deadline(time.Time) DialOption
func LocalAddr(Addr) DialOption
func Network(string) DialOption
func TCPFastOpen() DialOption
func Timeout(time.Duration) DialOption
I'm pretty confident we could add Happy Eyeballs to this too.
Fixes #3097
Update #3610
Update #4842
R=golang-dev, r, dave, minux.ma, rsc
CC=golang-dev
https://golang.org/cl/7365049
2013-02-27 12:59:36 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
var (
|
|
|
|
// TCP is a dial option to dial with TCP (over IPv4 or IPv6).
|
|
|
|
TCP = Network("tcp")
|
|
|
|
|
|
|
|
// UDP is a dial option to dial with UDP (over IPv4 or IPv6).
|
|
|
|
UDP = Network("udp")
|
|
|
|
)
|
|
|
|
|
|
|
|
// Network returns a DialOption to dial using the given network.
|
|
|
|
//
|
|
|
|
// Known networks are "tcp", "tcp4" (IPv4-only), "tcp6" (IPv6-only),
|
|
|
|
// "udp", "udp4" (IPv4-only), "udp6" (IPv6-only), "ip", "ip4"
|
|
|
|
// (IPv4-only), "ip6" (IPv6-only), "unix", "unixgram" and
|
|
|
|
// "unixpacket".
|
|
|
|
//
|
|
|
|
// For IP networks, net must be "ip", "ip4" or "ip6" followed
|
|
|
|
// by a colon and a protocol number or name, such as
|
|
|
|
// "ipv4:1" or "ip6:ospf".
|
|
|
|
func Network(net string) DialOption {
|
|
|
|
return dialNetwork(net)
|
|
|
|
}
|
|
|
|
|
|
|
|
type dialNetwork string
|
|
|
|
|
2013-03-09 19:14:00 -07:00
|
|
|
func (s dialNetwork) setDialOpt(o *dialOpts) {
|
|
|
|
o.network = string(s)
|
|
|
|
}
|
net: add DialOpt, the extensible Dial w/ options dialer
Add DialOpt. So we have:
func Dial(net, addr string) (Conn, error)
func DialTimeout(net, addr string, timeout time.Duration) (Conn, error)
func DialOpt(addr string, opts ...DialOption) (Conn, error)
DialTimeout (and Dial) are regrettable in retrospect. Maybe
in a future Go we'll be back down to one Dial, with DialOpt
becoming Dial.
DialOpt looks like:
c, err := net.DialOpt("google.com:80") // tcp is default
c, err := net.DialOpt("google.com:80", net.Timeout(30 * time.Second))
c, err := net.DialOpt("google.com:80", net.TCPFastOpen())
c, err := net.DialOpt("google.com:80", net.LocalAddr(..))
c, err := net.DialOpt("google.com:53", net.Network("udp6"))
And then: (clustered in godoc)
type DialOption interface { /* private only */ }
func Deadline(time.Time) DialOption
func LocalAddr(Addr) DialOption
func Network(string) DialOption
func TCPFastOpen() DialOption
func Timeout(time.Duration) DialOption
I'm pretty confident we could add Happy Eyeballs to this too.
Fixes #3097
Update #3610
Update #4842
R=golang-dev, r, dave, minux.ma, rsc
CC=golang-dev
https://golang.org/cl/7365049
2013-02-27 12:59:36 -07:00
|
|
|
|
|
|
|
// Deadline returns a DialOption to fail a dial that doesn't
|
|
|
|
// complete before t.
|
|
|
|
func Deadline(t time.Time) DialOption {
|
|
|
|
return dialDeadline(t)
|
|
|
|
}
|
|
|
|
|
2013-03-09 19:14:00 -07:00
|
|
|
type dialDeadline time.Time
|
|
|
|
|
|
|
|
func (t dialDeadline) setDialOpt(o *dialOpts) {
|
|
|
|
o.deadline = time.Time(t)
|
|
|
|
}
|
|
|
|
|
net: add DialOpt, the extensible Dial w/ options dialer
Add DialOpt. So we have:
func Dial(net, addr string) (Conn, error)
func DialTimeout(net, addr string, timeout time.Duration) (Conn, error)
func DialOpt(addr string, opts ...DialOption) (Conn, error)
DialTimeout (and Dial) are regrettable in retrospect. Maybe
in a future Go we'll be back down to one Dial, with DialOpt
becoming Dial.
DialOpt looks like:
c, err := net.DialOpt("google.com:80") // tcp is default
c, err := net.DialOpt("google.com:80", net.Timeout(30 * time.Second))
c, err := net.DialOpt("google.com:80", net.TCPFastOpen())
c, err := net.DialOpt("google.com:80", net.LocalAddr(..))
c, err := net.DialOpt("google.com:53", net.Network("udp6"))
And then: (clustered in godoc)
type DialOption interface { /* private only */ }
func Deadline(time.Time) DialOption
func LocalAddr(Addr) DialOption
func Network(string) DialOption
func TCPFastOpen() DialOption
func Timeout(time.Duration) DialOption
I'm pretty confident we could add Happy Eyeballs to this too.
Fixes #3097
Update #3610
Update #4842
R=golang-dev, r, dave, minux.ma, rsc
CC=golang-dev
https://golang.org/cl/7365049
2013-02-27 12:59:36 -07:00
|
|
|
// Timeout returns a DialOption to fail a dial that doesn't
|
|
|
|
// complete within the provided duration.
|
|
|
|
func Timeout(d time.Duration) DialOption {
|
2013-03-09 19:14:00 -07:00
|
|
|
return dialTimeoutOpt(d)
|
net: add DialOpt, the extensible Dial w/ options dialer
Add DialOpt. So we have:
func Dial(net, addr string) (Conn, error)
func DialTimeout(net, addr string, timeout time.Duration) (Conn, error)
func DialOpt(addr string, opts ...DialOption) (Conn, error)
DialTimeout (and Dial) are regrettable in retrospect. Maybe
in a future Go we'll be back down to one Dial, with DialOpt
becoming Dial.
DialOpt looks like:
c, err := net.DialOpt("google.com:80") // tcp is default
c, err := net.DialOpt("google.com:80", net.Timeout(30 * time.Second))
c, err := net.DialOpt("google.com:80", net.TCPFastOpen())
c, err := net.DialOpt("google.com:80", net.LocalAddr(..))
c, err := net.DialOpt("google.com:53", net.Network("udp6"))
And then: (clustered in godoc)
type DialOption interface { /* private only */ }
func Deadline(time.Time) DialOption
func LocalAddr(Addr) DialOption
func Network(string) DialOption
func TCPFastOpen() DialOption
func Timeout(time.Duration) DialOption
I'm pretty confident we could add Happy Eyeballs to this too.
Fixes #3097
Update #3610
Update #4842
R=golang-dev, r, dave, minux.ma, rsc
CC=golang-dev
https://golang.org/cl/7365049
2013-02-27 12:59:36 -07:00
|
|
|
}
|
|
|
|
|
2013-03-09 19:14:00 -07:00
|
|
|
type dialTimeoutOpt time.Duration
|
net: add DialOpt, the extensible Dial w/ options dialer
Add DialOpt. So we have:
func Dial(net, addr string) (Conn, error)
func DialTimeout(net, addr string, timeout time.Duration) (Conn, error)
func DialOpt(addr string, opts ...DialOption) (Conn, error)
DialTimeout (and Dial) are regrettable in retrospect. Maybe
in a future Go we'll be back down to one Dial, with DialOpt
becoming Dial.
DialOpt looks like:
c, err := net.DialOpt("google.com:80") // tcp is default
c, err := net.DialOpt("google.com:80", net.Timeout(30 * time.Second))
c, err := net.DialOpt("google.com:80", net.TCPFastOpen())
c, err := net.DialOpt("google.com:80", net.LocalAddr(..))
c, err := net.DialOpt("google.com:53", net.Network("udp6"))
And then: (clustered in godoc)
type DialOption interface { /* private only */ }
func Deadline(time.Time) DialOption
func LocalAddr(Addr) DialOption
func Network(string) DialOption
func TCPFastOpen() DialOption
func Timeout(time.Duration) DialOption
I'm pretty confident we could add Happy Eyeballs to this too.
Fixes #3097
Update #3610
Update #4842
R=golang-dev, r, dave, minux.ma, rsc
CC=golang-dev
https://golang.org/cl/7365049
2013-02-27 12:59:36 -07:00
|
|
|
|
2013-03-09 19:14:00 -07:00
|
|
|
func (d dialTimeoutOpt) setDialOpt(o *dialOpts) {
|
|
|
|
o.deadline = time.Now().Add(time.Duration(d))
|
|
|
|
}
|
net: add DialOpt, the extensible Dial w/ options dialer
Add DialOpt. So we have:
func Dial(net, addr string) (Conn, error)
func DialTimeout(net, addr string, timeout time.Duration) (Conn, error)
func DialOpt(addr string, opts ...DialOption) (Conn, error)
DialTimeout (and Dial) are regrettable in retrospect. Maybe
in a future Go we'll be back down to one Dial, with DialOpt
becoming Dial.
DialOpt looks like:
c, err := net.DialOpt("google.com:80") // tcp is default
c, err := net.DialOpt("google.com:80", net.Timeout(30 * time.Second))
c, err := net.DialOpt("google.com:80", net.TCPFastOpen())
c, err := net.DialOpt("google.com:80", net.LocalAddr(..))
c, err := net.DialOpt("google.com:53", net.Network("udp6"))
And then: (clustered in godoc)
type DialOption interface { /* private only */ }
func Deadline(time.Time) DialOption
func LocalAddr(Addr) DialOption
func Network(string) DialOption
func TCPFastOpen() DialOption
func Timeout(time.Duration) DialOption
I'm pretty confident we could add Happy Eyeballs to this too.
Fixes #3097
Update #3610
Update #4842
R=golang-dev, r, dave, minux.ma, rsc
CC=golang-dev
https://golang.org/cl/7365049
2013-02-27 12:59:36 -07:00
|
|
|
|
|
|
|
type tcpFastOpen struct{}
|
|
|
|
|
2013-03-09 19:14:00 -07:00
|
|
|
func (tcpFastOpen) setDialOpt(o *dialOpts) {
|
|
|
|
o.deferredConnect = true
|
|
|
|
}
|
net: add DialOpt, the extensible Dial w/ options dialer
Add DialOpt. So we have:
func Dial(net, addr string) (Conn, error)
func DialTimeout(net, addr string, timeout time.Duration) (Conn, error)
func DialOpt(addr string, opts ...DialOption) (Conn, error)
DialTimeout (and Dial) are regrettable in retrospect. Maybe
in a future Go we'll be back down to one Dial, with DialOpt
becoming Dial.
DialOpt looks like:
c, err := net.DialOpt("google.com:80") // tcp is default
c, err := net.DialOpt("google.com:80", net.Timeout(30 * time.Second))
c, err := net.DialOpt("google.com:80", net.TCPFastOpen())
c, err := net.DialOpt("google.com:80", net.LocalAddr(..))
c, err := net.DialOpt("google.com:53", net.Network("udp6"))
And then: (clustered in godoc)
type DialOption interface { /* private only */ }
func Deadline(time.Time) DialOption
func LocalAddr(Addr) DialOption
func Network(string) DialOption
func TCPFastOpen() DialOption
func Timeout(time.Duration) DialOption
I'm pretty confident we could add Happy Eyeballs to this too.
Fixes #3097
Update #3610
Update #4842
R=golang-dev, r, dave, minux.ma, rsc
CC=golang-dev
https://golang.org/cl/7365049
2013-02-27 12:59:36 -07:00
|
|
|
|
|
|
|
// TODO(bradfitz): implement this (golang.org/issue/4842) and unexport this.
|
|
|
|
//
|
|
|
|
// TCPFastTimeout returns an option to use TCP Fast Open (TFO) when
|
|
|
|
// doing this dial. It is only valid for use with TCP connections.
|
|
|
|
// Data sent over a TFO connection may be processed by the peer
|
|
|
|
// multiple times, so should be used with caution.
|
|
|
|
func todo_TCPFastTimeout() DialOption {
|
|
|
|
return tcpFastOpen{}
|
|
|
|
}
|
|
|
|
|
|
|
|
type localAddrOption struct {
|
|
|
|
la Addr
|
|
|
|
}
|
|
|
|
|
2013-03-09 19:14:00 -07:00
|
|
|
func (a localAddrOption) setDialOpt(o *dialOpts) {
|
|
|
|
o.localAddr = a.la
|
|
|
|
}
|
net: add DialOpt, the extensible Dial w/ options dialer
Add DialOpt. So we have:
func Dial(net, addr string) (Conn, error)
func DialTimeout(net, addr string, timeout time.Duration) (Conn, error)
func DialOpt(addr string, opts ...DialOption) (Conn, error)
DialTimeout (and Dial) are regrettable in retrospect. Maybe
in a future Go we'll be back down to one Dial, with DialOpt
becoming Dial.
DialOpt looks like:
c, err := net.DialOpt("google.com:80") // tcp is default
c, err := net.DialOpt("google.com:80", net.Timeout(30 * time.Second))
c, err := net.DialOpt("google.com:80", net.TCPFastOpen())
c, err := net.DialOpt("google.com:80", net.LocalAddr(..))
c, err := net.DialOpt("google.com:53", net.Network("udp6"))
And then: (clustered in godoc)
type DialOption interface { /* private only */ }
func Deadline(time.Time) DialOption
func LocalAddr(Addr) DialOption
func Network(string) DialOption
func TCPFastOpen() DialOption
func Timeout(time.Duration) DialOption
I'm pretty confident we could add Happy Eyeballs to this too.
Fixes #3097
Update #3610
Update #4842
R=golang-dev, r, dave, minux.ma, rsc
CC=golang-dev
https://golang.org/cl/7365049
2013-02-27 12:59:36 -07:00
|
|
|
|
|
|
|
// LocalAddress returns a dial option to perform a dial with the
|
|
|
|
// provided local address. The address must be of a compatible type
|
|
|
|
// for the network being dialed.
|
|
|
|
func LocalAddress(addr Addr) DialOption {
|
|
|
|
return localAddrOption{addr}
|
|
|
|
}
|
2011-12-20 14:17:39 -07:00
|
|
|
|
2013-02-08 05:53:10 -07:00
|
|
|
func parseNetwork(net string) (afnet string, proto int, err error) {
|
2012-01-21 05:51:53 -07:00
|
|
|
i := last(net, ':')
|
|
|
|
if i < 0 { // no colon
|
|
|
|
switch net {
|
|
|
|
case "tcp", "tcp4", "tcp6":
|
|
|
|
case "udp", "udp4", "udp6":
|
2012-11-27 14:36:05 -07:00
|
|
|
case "ip", "ip4", "ip6":
|
2012-01-21 05:51:53 -07:00
|
|
|
case "unix", "unixgram", "unixpacket":
|
|
|
|
default:
|
|
|
|
return "", 0, UnknownNetworkError(net)
|
|
|
|
}
|
|
|
|
return net, 0, nil
|
2011-06-29 22:56:13 -06:00
|
|
|
}
|
2012-01-21 05:51:53 -07:00
|
|
|
afnet = net[:i]
|
|
|
|
switch afnet {
|
2011-06-29 22:56:13 -06:00
|
|
|
case "ip", "ip4", "ip6":
|
2012-01-21 05:51:53 -07:00
|
|
|
protostr := net[i+1:]
|
|
|
|
proto, i, ok := dtoi(protostr, 0)
|
|
|
|
if !ok || i != len(protostr) {
|
|
|
|
proto, err = lookupProtocol(protostr)
|
|
|
|
if err != nil {
|
|
|
|
return "", 0, err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return afnet, proto, nil
|
2011-06-29 22:56:13 -06:00
|
|
|
}
|
2012-01-21 05:51:53 -07:00
|
|
|
return "", 0, UnknownNetworkError(net)
|
|
|
|
}
|
|
|
|
|
2013-02-08 05:53:10 -07:00
|
|
|
func resolveAddr(op, net, addr string, deadline time.Time) (Addr, error) {
|
|
|
|
afnet, _, err := parseNetwork(net)
|
2011-06-29 22:56:13 -06:00
|
|
|
if err != nil {
|
2013-02-08 05:53:10 -07:00
|
|
|
return nil, &OpError{op, net, nil, err}
|
2012-01-21 05:51:53 -07:00
|
|
|
}
|
|
|
|
if op == "dial" && addr == "" {
|
2013-02-08 05:53:10 -07:00
|
|
|
return nil, &OpError{op, net, nil, errMissingAddress}
|
2012-11-08 09:35:16 -07:00
|
|
|
}
|
2012-01-21 05:51:53 -07:00
|
|
|
switch afnet {
|
|
|
|
case "unix", "unixgram", "unixpacket":
|
2012-11-08 09:35:16 -07:00
|
|
|
return ResolveUnixAddr(afnet, addr)
|
2011-06-29 22:56:13 -06:00
|
|
|
}
|
2013-02-08 05:53:10 -07:00
|
|
|
return resolveInternetAddr(afnet, addr, deadline)
|
2011-06-29 22:56:13 -06:00
|
|
|
}
|
|
|
|
|
2011-03-28 21:28:42 -06:00
|
|
|
// Dial connects to the address addr on the network net.
|
2010-06-21 20:52:30 -06:00
|
|
|
//
|
|
|
|
// Known networks are "tcp", "tcp4" (IPv4-only), "tcp6" (IPv6-only),
|
|
|
|
// "udp", "udp4" (IPv4-only), "udp6" (IPv6-only), "ip", "ip4"
|
2013-02-08 16:18:32 -07:00
|
|
|
// (IPv4-only), "ip6" (IPv6-only), "unix", "unixgram" and
|
|
|
|
// "unixpacket".
|
2010-06-21 20:52:30 -06:00
|
|
|
//
|
2012-01-21 05:51:53 -07:00
|
|
|
// For TCP and UDP networks, addresses have the form host:port.
|
net: support IPv6 scoped addressing zone
This CL provides IPv6 scoped addressing zone support as defined
in RFC 4007 for internet protocol family connection setups.
Follwoing types and functions allow a literal IPv6 address with
zone identifer as theirs parameter.
pkg net, func Dial(string, string) (Conn, error)
pkg net, func DialOpt(string, ...DialOption) (Conn, error)
pkg net, func DialTimeout(string, string, time.Duration) (Conn, error)
pkg net, func Listen(string, string) (Listener, error)
pkg net, func ListenPacket(string, string) (PacketConn, error)
pkg net, func ResolveIPAddr(string, string) (*IPAddr, error)
pkg net, func ResolveTCPAddr(string, string) (*TCPAddr, error)
pkg net, func ResolveUDPAddr(string, string) (*UDPAddr, error)
pkg net, type IPAddr struct, Zone string
pkg net, type TCPAddr struct, Zone string
pkg net, type UDPAddr struct, Zone string
Also follwoing methods return a literal IPv6 address with zone
identifier string if possible.
pkg net, method (*IPAddr) String() string
pkg net, method (*TCPAddr) String() string
pkg net, method (*UDPAddr) String() string
Fixes #4234.
Fixes #4501.
Update #5081.
R=rsc, iant
CC=golang-dev
https://golang.org/cl/6816116
2013-03-22 18:57:40 -06:00
|
|
|
// If host is a literal IPv6 address or host name, it must be enclosed
|
|
|
|
// in square brackets as in "[::1]:80", "[ipv6-host]:http" or
|
|
|
|
// "[ipv6-host%zone]:80".
|
|
|
|
// The functions JoinHostPort and SplitHostPort manipulate addresses
|
|
|
|
// in this form.
|
2010-06-21 20:52:30 -06:00
|
|
|
//
|
|
|
|
// Examples:
|
2011-03-28 21:28:42 -06:00
|
|
|
// Dial("tcp", "12.34.56.78:80")
|
net: support IPv6 scoped addressing zone
This CL provides IPv6 scoped addressing zone support as defined
in RFC 4007 for internet protocol family connection setups.
Follwoing types and functions allow a literal IPv6 address with
zone identifer as theirs parameter.
pkg net, func Dial(string, string) (Conn, error)
pkg net, func DialOpt(string, ...DialOption) (Conn, error)
pkg net, func DialTimeout(string, string, time.Duration) (Conn, error)
pkg net, func Listen(string, string) (Listener, error)
pkg net, func ListenPacket(string, string) (PacketConn, error)
pkg net, func ResolveIPAddr(string, string) (*IPAddr, error)
pkg net, func ResolveTCPAddr(string, string) (*TCPAddr, error)
pkg net, func ResolveUDPAddr(string, string) (*UDPAddr, error)
pkg net, type IPAddr struct, Zone string
pkg net, type TCPAddr struct, Zone string
pkg net, type UDPAddr struct, Zone string
Also follwoing methods return a literal IPv6 address with zone
identifier string if possible.
pkg net, method (*IPAddr) String() string
pkg net, method (*TCPAddr) String() string
pkg net, method (*UDPAddr) String() string
Fixes #4234.
Fixes #4501.
Update #5081.
R=rsc, iant
CC=golang-dev
https://golang.org/cl/6816116
2013-03-22 18:57:40 -06:00
|
|
|
// Dial("tcp", "google.com:http")
|
|
|
|
// Dial("tcp", "[2001:db8::1]:http")
|
|
|
|
// Dial("tcp", "[fe80::1%lo0]:80")
|
2010-06-21 20:52:30 -06:00
|
|
|
//
|
net: support IPv6 scoped addressing zone
This CL provides IPv6 scoped addressing zone support as defined
in RFC 4007 for internet protocol family connection setups.
Follwoing types and functions allow a literal IPv6 address with
zone identifer as theirs parameter.
pkg net, func Dial(string, string) (Conn, error)
pkg net, func DialOpt(string, ...DialOption) (Conn, error)
pkg net, func DialTimeout(string, string, time.Duration) (Conn, error)
pkg net, func Listen(string, string) (Listener, error)
pkg net, func ListenPacket(string, string) (PacketConn, error)
pkg net, func ResolveIPAddr(string, string) (*IPAddr, error)
pkg net, func ResolveTCPAddr(string, string) (*TCPAddr, error)
pkg net, func ResolveUDPAddr(string, string) (*UDPAddr, error)
pkg net, type IPAddr struct, Zone string
pkg net, type TCPAddr struct, Zone string
pkg net, type UDPAddr struct, Zone string
Also follwoing methods return a literal IPv6 address with zone
identifier string if possible.
pkg net, method (*IPAddr) String() string
pkg net, method (*TCPAddr) String() string
pkg net, method (*UDPAddr) String() string
Fixes #4234.
Fixes #4501.
Update #5081.
R=rsc, iant
CC=golang-dev
https://golang.org/cl/6816116
2013-03-22 18:57:40 -06:00
|
|
|
// For IP networks, the net must be "ip", "ip4" or "ip6" followed by a
|
|
|
|
// colon and a protocol number or name and the addr must be a literal
|
|
|
|
// IP address.
|
2012-01-21 05:51:53 -07:00
|
|
|
//
|
|
|
|
// Examples:
|
|
|
|
// Dial("ip4:1", "127.0.0.1")
|
|
|
|
// Dial("ip6:ospf", "::1")
|
|
|
|
//
|
net: support IPv6 scoped addressing zone
This CL provides IPv6 scoped addressing zone support as defined
in RFC 4007 for internet protocol family connection setups.
Follwoing types and functions allow a literal IPv6 address with
zone identifer as theirs parameter.
pkg net, func Dial(string, string) (Conn, error)
pkg net, func DialOpt(string, ...DialOption) (Conn, error)
pkg net, func DialTimeout(string, string, time.Duration) (Conn, error)
pkg net, func Listen(string, string) (Listener, error)
pkg net, func ListenPacket(string, string) (PacketConn, error)
pkg net, func ResolveIPAddr(string, string) (*IPAddr, error)
pkg net, func ResolveTCPAddr(string, string) (*TCPAddr, error)
pkg net, func ResolveUDPAddr(string, string) (*UDPAddr, error)
pkg net, type IPAddr struct, Zone string
pkg net, type TCPAddr struct, Zone string
pkg net, type UDPAddr struct, Zone string
Also follwoing methods return a literal IPv6 address with zone
identifier string if possible.
pkg net, method (*IPAddr) String() string
pkg net, method (*TCPAddr) String() string
pkg net, method (*UDPAddr) String() string
Fixes #4234.
Fixes #4501.
Update #5081.
R=rsc, iant
CC=golang-dev
https://golang.org/cl/6816116
2013-03-22 18:57:40 -06:00
|
|
|
// For Unix networks, the addr must be a file system path.
|
2011-12-20 14:17:39 -07:00
|
|
|
func Dial(net, addr string) (Conn, error) {
|
net: add DialOpt, the extensible Dial w/ options dialer
Add DialOpt. So we have:
func Dial(net, addr string) (Conn, error)
func DialTimeout(net, addr string, timeout time.Duration) (Conn, error)
func DialOpt(addr string, opts ...DialOption) (Conn, error)
DialTimeout (and Dial) are regrettable in retrospect. Maybe
in a future Go we'll be back down to one Dial, with DialOpt
becoming Dial.
DialOpt looks like:
c, err := net.DialOpt("google.com:80") // tcp is default
c, err := net.DialOpt("google.com:80", net.Timeout(30 * time.Second))
c, err := net.DialOpt("google.com:80", net.TCPFastOpen())
c, err := net.DialOpt("google.com:80", net.LocalAddr(..))
c, err := net.DialOpt("google.com:53", net.Network("udp6"))
And then: (clustered in godoc)
type DialOption interface { /* private only */ }
func Deadline(time.Time) DialOption
func LocalAddr(Addr) DialOption
func Network(string) DialOption
func TCPFastOpen() DialOption
func Timeout(time.Duration) DialOption
I'm pretty confident we could add Happy Eyeballs to this too.
Fixes #3097
Update #3610
Update #4842
R=golang-dev, r, dave, minux.ma, rsc
CC=golang-dev
https://golang.org/cl/7365049
2013-02-27 12:59:36 -07:00
|
|
|
return DialOpt(addr, dialNetwork(net))
|
|
|
|
}
|
|
|
|
|
|
|
|
// DialOpt dials addr using the provided options.
|
|
|
|
// If no options are provided, DialOpt(addr) is equivalent
|
|
|
|
// to Dial("tcp", addr). See Dial for the syntax of addr.
|
|
|
|
func DialOpt(addr string, opts ...DialOption) (Conn, error) {
|
2013-03-09 19:14:00 -07:00
|
|
|
var o dialOpts
|
|
|
|
for _, opt := range opts {
|
|
|
|
opt.setDialOpt(&o)
|
|
|
|
}
|
|
|
|
ra, err := resolveAddr("dial", o.net(), addr, o.deadline)
|
2011-06-29 22:56:13 -06:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
2011-03-28 21:28:42 -06:00
|
|
|
}
|
2013-03-09 19:14:00 -07:00
|
|
|
return dial(o.net(), addr, o.localAddr, ra, o.deadline)
|
2011-12-20 14:17:39 -07:00
|
|
|
}
|
|
|
|
|
net: add DialOpt, the extensible Dial w/ options dialer
Add DialOpt. So we have:
func Dial(net, addr string) (Conn, error)
func DialTimeout(net, addr string, timeout time.Duration) (Conn, error)
func DialOpt(addr string, opts ...DialOption) (Conn, error)
DialTimeout (and Dial) are regrettable in retrospect. Maybe
in a future Go we'll be back down to one Dial, with DialOpt
becoming Dial.
DialOpt looks like:
c, err := net.DialOpt("google.com:80") // tcp is default
c, err := net.DialOpt("google.com:80", net.Timeout(30 * time.Second))
c, err := net.DialOpt("google.com:80", net.TCPFastOpen())
c, err := net.DialOpt("google.com:80", net.LocalAddr(..))
c, err := net.DialOpt("google.com:53", net.Network("udp6"))
And then: (clustered in godoc)
type DialOption interface { /* private only */ }
func Deadline(time.Time) DialOption
func LocalAddr(Addr) DialOption
func Network(string) DialOption
func TCPFastOpen() DialOption
func Timeout(time.Duration) DialOption
I'm pretty confident we could add Happy Eyeballs to this too.
Fixes #3097
Update #3610
Update #4842
R=golang-dev, r, dave, minux.ma, rsc
CC=golang-dev
https://golang.org/cl/7365049
2013-02-27 12:59:36 -07:00
|
|
|
func dial(net, addr string, la, ra Addr, deadline time.Time) (c Conn, err error) {
|
|
|
|
if la != nil && la.Network() != ra.Network() {
|
|
|
|
return nil, &OpError{"dial", net, ra, errors.New("mismatched local addr type " + la.Network())}
|
|
|
|
}
|
2013-02-08 05:53:10 -07:00
|
|
|
switch ra := ra.(type) {
|
2011-06-29 22:56:13 -06:00
|
|
|
case *TCPAddr:
|
net: add DialOpt, the extensible Dial w/ options dialer
Add DialOpt. So we have:
func Dial(net, addr string) (Conn, error)
func DialTimeout(net, addr string, timeout time.Duration) (Conn, error)
func DialOpt(addr string, opts ...DialOption) (Conn, error)
DialTimeout (and Dial) are regrettable in retrospect. Maybe
in a future Go we'll be back down to one Dial, with DialOpt
becoming Dial.
DialOpt looks like:
c, err := net.DialOpt("google.com:80") // tcp is default
c, err := net.DialOpt("google.com:80", net.Timeout(30 * time.Second))
c, err := net.DialOpt("google.com:80", net.TCPFastOpen())
c, err := net.DialOpt("google.com:80", net.LocalAddr(..))
c, err := net.DialOpt("google.com:53", net.Network("udp6"))
And then: (clustered in godoc)
type DialOption interface { /* private only */ }
func Deadline(time.Time) DialOption
func LocalAddr(Addr) DialOption
func Network(string) DialOption
func TCPFastOpen() DialOption
func Timeout(time.Duration) DialOption
I'm pretty confident we could add Happy Eyeballs to this too.
Fixes #3097
Update #3610
Update #4842
R=golang-dev, r, dave, minux.ma, rsc
CC=golang-dev
https://golang.org/cl/7365049
2013-02-27 12:59:36 -07:00
|
|
|
la, _ := la.(*TCPAddr)
|
|
|
|
c, err = dialTCP(net, la, ra, deadline)
|
2011-06-29 22:56:13 -06:00
|
|
|
case *UDPAddr:
|
net: add DialOpt, the extensible Dial w/ options dialer
Add DialOpt. So we have:
func Dial(net, addr string) (Conn, error)
func DialTimeout(net, addr string, timeout time.Duration) (Conn, error)
func DialOpt(addr string, opts ...DialOption) (Conn, error)
DialTimeout (and Dial) are regrettable in retrospect. Maybe
in a future Go we'll be back down to one Dial, with DialOpt
becoming Dial.
DialOpt looks like:
c, err := net.DialOpt("google.com:80") // tcp is default
c, err := net.DialOpt("google.com:80", net.Timeout(30 * time.Second))
c, err := net.DialOpt("google.com:80", net.TCPFastOpen())
c, err := net.DialOpt("google.com:80", net.LocalAddr(..))
c, err := net.DialOpt("google.com:53", net.Network("udp6"))
And then: (clustered in godoc)
type DialOption interface { /* private only */ }
func Deadline(time.Time) DialOption
func LocalAddr(Addr) DialOption
func Network(string) DialOption
func TCPFastOpen() DialOption
func Timeout(time.Duration) DialOption
I'm pretty confident we could add Happy Eyeballs to this too.
Fixes #3097
Update #3610
Update #4842
R=golang-dev, r, dave, minux.ma, rsc
CC=golang-dev
https://golang.org/cl/7365049
2013-02-27 12:59:36 -07:00
|
|
|
la, _ := la.(*UDPAddr)
|
|
|
|
c, err = dialUDP(net, la, ra, deadline)
|
2011-06-29 22:56:13 -06:00
|
|
|
case *IPAddr:
|
net: add DialOpt, the extensible Dial w/ options dialer
Add DialOpt. So we have:
func Dial(net, addr string) (Conn, error)
func DialTimeout(net, addr string, timeout time.Duration) (Conn, error)
func DialOpt(addr string, opts ...DialOption) (Conn, error)
DialTimeout (and Dial) are regrettable in retrospect. Maybe
in a future Go we'll be back down to one Dial, with DialOpt
becoming Dial.
DialOpt looks like:
c, err := net.DialOpt("google.com:80") // tcp is default
c, err := net.DialOpt("google.com:80", net.Timeout(30 * time.Second))
c, err := net.DialOpt("google.com:80", net.TCPFastOpen())
c, err := net.DialOpt("google.com:80", net.LocalAddr(..))
c, err := net.DialOpt("google.com:53", net.Network("udp6"))
And then: (clustered in godoc)
type DialOption interface { /* private only */ }
func Deadline(time.Time) DialOption
func LocalAddr(Addr) DialOption
func Network(string) DialOption
func TCPFastOpen() DialOption
func Timeout(time.Duration) DialOption
I'm pretty confident we could add Happy Eyeballs to this too.
Fixes #3097
Update #3610
Update #4842
R=golang-dev, r, dave, minux.ma, rsc
CC=golang-dev
https://golang.org/cl/7365049
2013-02-27 12:59:36 -07:00
|
|
|
la, _ := la.(*IPAddr)
|
|
|
|
c, err = dialIP(net, la, ra, deadline)
|
2012-01-21 05:51:53 -07:00
|
|
|
case *UnixAddr:
|
net: add DialOpt, the extensible Dial w/ options dialer
Add DialOpt. So we have:
func Dial(net, addr string) (Conn, error)
func DialTimeout(net, addr string, timeout time.Duration) (Conn, error)
func DialOpt(addr string, opts ...DialOption) (Conn, error)
DialTimeout (and Dial) are regrettable in retrospect. Maybe
in a future Go we'll be back down to one Dial, with DialOpt
becoming Dial.
DialOpt looks like:
c, err := net.DialOpt("google.com:80") // tcp is default
c, err := net.DialOpt("google.com:80", net.Timeout(30 * time.Second))
c, err := net.DialOpt("google.com:80", net.TCPFastOpen())
c, err := net.DialOpt("google.com:80", net.LocalAddr(..))
c, err := net.DialOpt("google.com:53", net.Network("udp6"))
And then: (clustered in godoc)
type DialOption interface { /* private only */ }
func Deadline(time.Time) DialOption
func LocalAddr(Addr) DialOption
func Network(string) DialOption
func TCPFastOpen() DialOption
func Timeout(time.Duration) DialOption
I'm pretty confident we could add Happy Eyeballs to this too.
Fixes #3097
Update #3610
Update #4842
R=golang-dev, r, dave, minux.ma, rsc
CC=golang-dev
https://golang.org/cl/7365049
2013-02-27 12:59:36 -07:00
|
|
|
la, _ := la.(*UnixAddr)
|
|
|
|
c, err = dialUnix(net, la, ra, deadline)
|
2011-06-29 22:56:13 -06:00
|
|
|
default:
|
net: add DialOpt, the extensible Dial w/ options dialer
Add DialOpt. So we have:
func Dial(net, addr string) (Conn, error)
func DialTimeout(net, addr string, timeout time.Duration) (Conn, error)
func DialOpt(addr string, opts ...DialOption) (Conn, error)
DialTimeout (and Dial) are regrettable in retrospect. Maybe
in a future Go we'll be back down to one Dial, with DialOpt
becoming Dial.
DialOpt looks like:
c, err := net.DialOpt("google.com:80") // tcp is default
c, err := net.DialOpt("google.com:80", net.Timeout(30 * time.Second))
c, err := net.DialOpt("google.com:80", net.TCPFastOpen())
c, err := net.DialOpt("google.com:80", net.LocalAddr(..))
c, err := net.DialOpt("google.com:53", net.Network("udp6"))
And then: (clustered in godoc)
type DialOption interface { /* private only */ }
func Deadline(time.Time) DialOption
func LocalAddr(Addr) DialOption
func Network(string) DialOption
func TCPFastOpen() DialOption
func Timeout(time.Duration) DialOption
I'm pretty confident we could add Happy Eyeballs to this too.
Fixes #3097
Update #3610
Update #4842
R=golang-dev, r, dave, minux.ma, rsc
CC=golang-dev
https://golang.org/cl/7365049
2013-02-27 12:59:36 -07:00
|
|
|
err = &OpError{"dial", net + " " + addr, ra, UnknownNetworkError(net)}
|
2011-06-29 22:56:13 -06:00
|
|
|
}
|
|
|
|
if err != nil {
|
2011-10-18 12:51:40 -06:00
|
|
|
return nil, err
|
2010-06-21 20:52:30 -06:00
|
|
|
}
|
2011-06-29 22:56:13 -06:00
|
|
|
return
|
2010-06-21 20:52:30 -06:00
|
|
|
}
|
|
|
|
|
2011-12-20 14:17:39 -07:00
|
|
|
// DialTimeout acts like Dial but takes a timeout.
|
|
|
|
// The timeout includes name resolution, if required.
|
|
|
|
func DialTimeout(net, addr string, timeout time.Duration) (Conn, error) {
|
2013-01-10 18:42:09 -07:00
|
|
|
return dialTimeout(net, addr, timeout)
|
2012-11-08 09:35:16 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// dialTimeoutRace is the old implementation of DialTimeout, still used
|
|
|
|
// on operating systems where the deadline hasn't been pushed down
|
|
|
|
// into the pollserver.
|
2013-01-10 18:42:09 -07:00
|
|
|
// TODO: fix this on plan9.
|
2012-11-08 09:35:16 -07:00
|
|
|
func dialTimeoutRace(net, addr string, timeout time.Duration) (Conn, error) {
|
2011-12-20 14:17:39 -07:00
|
|
|
t := time.NewTimer(timeout)
|
|
|
|
defer t.Stop()
|
|
|
|
type pair struct {
|
|
|
|
Conn
|
|
|
|
error
|
|
|
|
}
|
|
|
|
ch := make(chan pair, 1)
|
|
|
|
resolvedAddr := make(chan Addr, 1)
|
|
|
|
go func() {
|
2013-02-08 05:53:10 -07:00
|
|
|
ra, err := resolveAddr("dial", net, addr, noDeadline)
|
2011-12-20 14:17:39 -07:00
|
|
|
if err != nil {
|
|
|
|
ch <- pair{nil, err}
|
|
|
|
return
|
|
|
|
}
|
2013-02-08 05:53:10 -07:00
|
|
|
resolvedAddr <- ra // in case we need it for OpError
|
net: add DialOpt, the extensible Dial w/ options dialer
Add DialOpt. So we have:
func Dial(net, addr string) (Conn, error)
func DialTimeout(net, addr string, timeout time.Duration) (Conn, error)
func DialOpt(addr string, opts ...DialOption) (Conn, error)
DialTimeout (and Dial) are regrettable in retrospect. Maybe
in a future Go we'll be back down to one Dial, with DialOpt
becoming Dial.
DialOpt looks like:
c, err := net.DialOpt("google.com:80") // tcp is default
c, err := net.DialOpt("google.com:80", net.Timeout(30 * time.Second))
c, err := net.DialOpt("google.com:80", net.TCPFastOpen())
c, err := net.DialOpt("google.com:80", net.LocalAddr(..))
c, err := net.DialOpt("google.com:53", net.Network("udp6"))
And then: (clustered in godoc)
type DialOption interface { /* private only */ }
func Deadline(time.Time) DialOption
func LocalAddr(Addr) DialOption
func Network(string) DialOption
func TCPFastOpen() DialOption
func Timeout(time.Duration) DialOption
I'm pretty confident we could add Happy Eyeballs to this too.
Fixes #3097
Update #3610
Update #4842
R=golang-dev, r, dave, minux.ma, rsc
CC=golang-dev
https://golang.org/cl/7365049
2013-02-27 12:59:36 -07:00
|
|
|
c, err := dial(net, addr, noLocalAddr, ra, noDeadline)
|
2011-12-20 14:17:39 -07:00
|
|
|
ch <- pair{c, err}
|
|
|
|
}()
|
|
|
|
select {
|
|
|
|
case <-t.C:
|
|
|
|
// Try to use the real Addr in our OpError, if we resolved it
|
|
|
|
// before the timeout. Otherwise we just use stringAddr.
|
2013-02-08 05:53:10 -07:00
|
|
|
var ra Addr
|
2011-12-20 14:17:39 -07:00
|
|
|
select {
|
|
|
|
case a := <-resolvedAddr:
|
2013-02-08 05:53:10 -07:00
|
|
|
ra = a
|
2011-12-20 14:17:39 -07:00
|
|
|
default:
|
2013-02-08 05:53:10 -07:00
|
|
|
ra = &stringAddr{net, addr}
|
2011-12-20 14:17:39 -07:00
|
|
|
}
|
|
|
|
err := &OpError{
|
|
|
|
Op: "dial",
|
|
|
|
Net: net,
|
2013-02-08 05:53:10 -07:00
|
|
|
Addr: ra,
|
2011-12-20 14:17:39 -07:00
|
|
|
Err: &timeoutError{},
|
|
|
|
}
|
|
|
|
return nil, err
|
|
|
|
case p := <-ch:
|
|
|
|
return p.Conn, p.error
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
type stringAddr struct {
|
|
|
|
net, addr string
|
|
|
|
}
|
|
|
|
|
|
|
|
func (a stringAddr) Network() string { return a.net }
|
|
|
|
func (a stringAddr) String() string { return a.addr }
|
|
|
|
|
2010-06-21 20:52:30 -06:00
|
|
|
// Listen announces on the local network address laddr.
|
net: support IPv6 scoped addressing zone
This CL provides IPv6 scoped addressing zone support as defined
in RFC 4007 for internet protocol family connection setups.
Follwoing types and functions allow a literal IPv6 address with
zone identifer as theirs parameter.
pkg net, func Dial(string, string) (Conn, error)
pkg net, func DialOpt(string, ...DialOption) (Conn, error)
pkg net, func DialTimeout(string, string, time.Duration) (Conn, error)
pkg net, func Listen(string, string) (Listener, error)
pkg net, func ListenPacket(string, string) (PacketConn, error)
pkg net, func ResolveIPAddr(string, string) (*IPAddr, error)
pkg net, func ResolveTCPAddr(string, string) (*TCPAddr, error)
pkg net, func ResolveUDPAddr(string, string) (*UDPAddr, error)
pkg net, type IPAddr struct, Zone string
pkg net, type TCPAddr struct, Zone string
pkg net, type UDPAddr struct, Zone string
Also follwoing methods return a literal IPv6 address with zone
identifier string if possible.
pkg net, method (*IPAddr) String() string
pkg net, method (*TCPAddr) String() string
pkg net, method (*UDPAddr) String() string
Fixes #4234.
Fixes #4501.
Update #5081.
R=rsc, iant
CC=golang-dev
https://golang.org/cl/6816116
2013-03-22 18:57:40 -06:00
|
|
|
// The network net must be a stream-oriented network: "tcp", "tcp4",
|
|
|
|
// "tcp6", "unix" or "unixpacket".
|
|
|
|
// See Dial for the syntax of laddr.
|
2012-01-21 05:51:53 -07:00
|
|
|
func Listen(net, laddr string) (Listener, error) {
|
2013-02-08 05:53:10 -07:00
|
|
|
la, err := resolveAddr("listen", net, laddr, noDeadline)
|
2012-01-21 05:51:53 -07:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2013-02-08 05:53:10 -07:00
|
|
|
switch la := la.(type) {
|
|
|
|
case *TCPAddr:
|
2012-02-14 09:59:18 -07:00
|
|
|
return ListenTCP(net, la)
|
2013-02-08 05:53:10 -07:00
|
|
|
case *UnixAddr:
|
2012-01-21 05:51:53 -07:00
|
|
|
return ListenUnix(net, la)
|
2010-06-21 20:52:30 -06:00
|
|
|
}
|
|
|
|
return nil, UnknownNetworkError(net)
|
|
|
|
}
|
|
|
|
|
|
|
|
// ListenPacket announces on the local network address laddr.
|
net: support IPv6 scoped addressing zone
This CL provides IPv6 scoped addressing zone support as defined
in RFC 4007 for internet protocol family connection setups.
Follwoing types and functions allow a literal IPv6 address with
zone identifer as theirs parameter.
pkg net, func Dial(string, string) (Conn, error)
pkg net, func DialOpt(string, ...DialOption) (Conn, error)
pkg net, func DialTimeout(string, string, time.Duration) (Conn, error)
pkg net, func Listen(string, string) (Listener, error)
pkg net, func ListenPacket(string, string) (PacketConn, error)
pkg net, func ResolveIPAddr(string, string) (*IPAddr, error)
pkg net, func ResolveTCPAddr(string, string) (*TCPAddr, error)
pkg net, func ResolveUDPAddr(string, string) (*UDPAddr, error)
pkg net, type IPAddr struct, Zone string
pkg net, type TCPAddr struct, Zone string
pkg net, type UDPAddr struct, Zone string
Also follwoing methods return a literal IPv6 address with zone
identifier string if possible.
pkg net, method (*IPAddr) String() string
pkg net, method (*TCPAddr) String() string
pkg net, method (*UDPAddr) String() string
Fixes #4234.
Fixes #4501.
Update #5081.
R=rsc, iant
CC=golang-dev
https://golang.org/cl/6816116
2013-03-22 18:57:40 -06:00
|
|
|
// The network net must be a packet-oriented network: "udp", "udp4",
|
|
|
|
// "udp6", "ip", "ip4", "ip6" or "unixgram".
|
|
|
|
// See Dial for the syntax of laddr.
|
2012-11-27 14:36:05 -07:00
|
|
|
func ListenPacket(net, laddr string) (PacketConn, error) {
|
2013-02-08 05:53:10 -07:00
|
|
|
la, err := resolveAddr("listen", net, laddr, noDeadline)
|
2012-01-21 05:51:53 -07:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2013-02-08 05:53:10 -07:00
|
|
|
switch la := la.(type) {
|
|
|
|
case *UDPAddr:
|
2012-01-21 05:51:53 -07:00
|
|
|
return ListenUDP(net, la)
|
2013-02-08 05:53:10 -07:00
|
|
|
case *IPAddr:
|
2012-01-21 05:51:53 -07:00
|
|
|
return ListenIP(net, la)
|
2013-02-08 05:53:10 -07:00
|
|
|
case *UnixAddr:
|
2012-12-15 19:51:47 -07:00
|
|
|
return ListenUnixgram(net, la)
|
2011-02-16 13:03:47 -07:00
|
|
|
}
|
2010-06-21 20:52:30 -06:00
|
|
|
return nil, UnknownNetworkError(net)
|
|
|
|
}
|