Commit 6dfd3860 authored by Mikio Hara's avatar Mikio Hara

net: simplify Dial, Listen, ListenPacket and those helpers

R=golang-dev, dave, bradfitz
CC=golang-dev
https://golang.org/cl/7300065
parent dc6e51cf
...@@ -4,11 +4,9 @@ ...@@ -4,11 +4,9 @@
package net package net
import ( import "time"
"time"
)
func parseDialNetwork(net string) (afnet string, proto int, err error) { func parseNetwork(net string) (afnet string, proto int, err error) {
i := last(net, ':') i := last(net, ':')
if i < 0 { // no colon if i < 0 { // no colon
switch net { switch net {
...@@ -37,29 +35,19 @@ func parseDialNetwork(net string) (afnet string, proto int, err error) { ...@@ -37,29 +35,19 @@ func parseDialNetwork(net string) (afnet string, proto int, err error) {
return "", 0, UnknownNetworkError(net) return "", 0, UnknownNetworkError(net)
} }
func resolveNetAddr(op, net, addr string, deadline time.Time) (afnet string, a Addr, err error) { func resolveAddr(op, net, addr string, deadline time.Time) (Addr, error) {
afnet, _, err = parseDialNetwork(net) afnet, _, err := parseNetwork(net)
if err != nil { if err != nil {
return "", nil, &OpError{op, net, nil, err} return nil, &OpError{op, net, nil, err}
} }
if op == "dial" && addr == "" { if op == "dial" && addr == "" {
return "", nil, &OpError{op, net, nil, errMissingAddress} return nil, &OpError{op, net, nil, errMissingAddress}
}
a, err = resolveAfnetAddr(afnet, addr, deadline)
return
}
func resolveAfnetAddr(afnet, addr string, deadline time.Time) (Addr, error) {
if addr == "" {
return nil, nil
} }
switch afnet { switch afnet {
case "tcp", "tcp4", "tcp6", "udp", "udp4", "udp6", "ip", "ip4", "ip6":
return resolveInternetAddr(afnet, addr, deadline)
case "unix", "unixgram", "unixpacket": case "unix", "unixgram", "unixpacket":
return ResolveUnixAddr(afnet, addr) return ResolveUnixAddr(afnet, addr)
} }
return nil, nil return resolveInternetAddr(afnet, addr, deadline)
} }
// Dial connects to the address addr on the network net. // Dial connects to the address addr on the network net.
...@@ -86,15 +74,15 @@ func resolveAfnetAddr(afnet, addr string, deadline time.Time) (Addr, error) { ...@@ -86,15 +74,15 @@ func resolveAfnetAddr(afnet, addr string, deadline time.Time) (Addr, error) {
// Dial("ip6:ospf", "::1") // Dial("ip6:ospf", "::1")
// //
func Dial(net, addr string) (Conn, error) { func Dial(net, addr string) (Conn, error) {
_, addri, err := resolveNetAddr("dial", net, addr, noDeadline) ra, err := resolveAddr("dial", net, addr, noDeadline)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return dialAddr(net, addr, addri, noDeadline) return dial(net, addr, ra, noDeadline)
} }
func dialAddr(net, addr string, addri Addr, deadline time.Time) (c Conn, err error) { func dial(net, addr string, ra Addr, deadline time.Time) (c Conn, err error) {
switch ra := addri.(type) { switch ra := ra.(type) {
case *TCPAddr: case *TCPAddr:
c, err = dialTCP(net, nil, ra, deadline) c, err = dialTCP(net, nil, ra, deadline)
case *UDPAddr: case *UDPAddr:
...@@ -132,30 +120,30 @@ func dialTimeoutRace(net, addr string, timeout time.Duration) (Conn, error) { ...@@ -132,30 +120,30 @@ func dialTimeoutRace(net, addr string, timeout time.Duration) (Conn, error) {
ch := make(chan pair, 1) ch := make(chan pair, 1)
resolvedAddr := make(chan Addr, 1) resolvedAddr := make(chan Addr, 1)
go func() { go func() {
_, addri, err := resolveNetAddr("dial", net, addr, noDeadline) ra, err := resolveAddr("dial", net, addr, noDeadline)
if err != nil { if err != nil {
ch <- pair{nil, err} ch <- pair{nil, err}
return return
} }
resolvedAddr <- addri // in case we need it for OpError resolvedAddr <- ra // in case we need it for OpError
c, err := dialAddr(net, addr, addri, noDeadline) c, err := dial(net, addr, ra, noDeadline)
ch <- pair{c, err} ch <- pair{c, err}
}() }()
select { select {
case <-t.C: case <-t.C:
// Try to use the real Addr in our OpError, if we resolved it // Try to use the real Addr in our OpError, if we resolved it
// before the timeout. Otherwise we just use stringAddr. // before the timeout. Otherwise we just use stringAddr.
var addri Addr var ra Addr
select { select {
case a := <-resolvedAddr: case a := <-resolvedAddr:
addri = a ra = a
default: default:
addri = &stringAddr{net, addr} ra = &stringAddr{net, addr}
} }
err := &OpError{ err := &OpError{
Op: "dial", Op: "dial",
Net: net, Net: net,
Addr: addri, Addr: ra,
Err: &timeoutError{}, Err: &timeoutError{},
} }
return nil, err return nil, err
...@@ -176,22 +164,14 @@ func (a stringAddr) String() string { return a.addr } ...@@ -176,22 +164,14 @@ func (a stringAddr) String() string { return a.addr }
// The network string net must be a stream-oriented network: // The network string net must be a stream-oriented network:
// "tcp", "tcp4", "tcp6", "unix" or "unixpacket". // "tcp", "tcp4", "tcp6", "unix" or "unixpacket".
func Listen(net, laddr string) (Listener, error) { func Listen(net, laddr string) (Listener, error) {
afnet, a, err := resolveNetAddr("listen", net, laddr, noDeadline) la, err := resolveAddr("listen", net, laddr, noDeadline)
if err != nil { if err != nil {
return nil, err return nil, err
} }
switch afnet { switch la := la.(type) {
case "tcp", "tcp4", "tcp6": case *TCPAddr:
var la *TCPAddr
if a != nil {
la = a.(*TCPAddr)
}
return ListenTCP(net, la) return ListenTCP(net, la)
case "unix", "unixpacket": case *UnixAddr:
var la *UnixAddr
if a != nil {
la = a.(*UnixAddr)
}
return ListenUnix(net, la) return ListenUnix(net, la)
} }
return nil, UnknownNetworkError(net) return nil, UnknownNetworkError(net)
...@@ -201,28 +181,16 @@ func Listen(net, laddr string) (Listener, error) { ...@@ -201,28 +181,16 @@ func Listen(net, laddr string) (Listener, error) {
// The network string net must be a packet-oriented network: // The network string net must be a packet-oriented network:
// "udp", "udp4", "udp6", "ip", "ip4", "ip6" or "unixgram". // "udp", "udp4", "udp6", "ip", "ip4", "ip6" or "unixgram".
func ListenPacket(net, laddr string) (PacketConn, error) { func ListenPacket(net, laddr string) (PacketConn, error) {
afnet, a, err := resolveNetAddr("listen", net, laddr, noDeadline) la, err := resolveAddr("listen", net, laddr, noDeadline)
if err != nil { if err != nil {
return nil, err return nil, err
} }
switch afnet { switch la := la.(type) {
case "udp", "udp4", "udp6": case *UDPAddr:
var la *UDPAddr
if a != nil {
la = a.(*UDPAddr)
}
return ListenUDP(net, la) return ListenUDP(net, la)
case "ip", "ip4", "ip6": case *IPAddr:
var la *IPAddr
if a != nil {
la = a.(*IPAddr)
}
return ListenIP(net, la) return ListenIP(net, la)
case "unixgram": case *UnixAddr:
var la *UnixAddr
if a != nil {
la = a.(*UnixAddr)
}
return ListenUnixgram(net, la) return ListenUnixgram(net, la)
} }
return nil, UnknownNetworkError(net) return nil, UnknownNetworkError(net)
......
...@@ -297,11 +297,11 @@ func server(fd int) *pollServer { ...@@ -297,11 +297,11 @@ func server(fd int) *pollServer {
func dialTimeout(net, addr string, timeout time.Duration) (Conn, error) { func dialTimeout(net, addr string, timeout time.Duration) (Conn, error) {
deadline := time.Now().Add(timeout) deadline := time.Now().Add(timeout)
_, addri, err := resolveNetAddr("dial", net, addr, deadline) ra, err := resolveAddr("dial", net, addr, deadline)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return dialAddr(net, addr, addri, deadline) return dial(net, addr, ra, deadline)
} }
func newFD(fd, family, sotype int, net string) (*netFD, error) { func newFD(fd, family, sotype int, net string) (*netFD, error) {
......
...@@ -61,11 +61,11 @@ func dialTimeout(net, addr string, timeout time.Duration) (Conn, error) { ...@@ -61,11 +61,11 @@ func dialTimeout(net, addr string, timeout time.Duration) (Conn, error) {
return dialTimeoutRace(net, addr, timeout) return dialTimeoutRace(net, addr, timeout)
} }
deadline := time.Now().Add(timeout) deadline := time.Now().Add(timeout)
_, addri, err := resolveNetAddr("dial", net, addr, deadline) ra, err := resolveAddr("dial", net, addr, deadline)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return dialAddr(net, addr, addri, deadline) return dial(net, addr, ra, deadline)
} }
// Interface for all IO operations. // Interface for all IO operations.
......
...@@ -182,7 +182,7 @@ const ( ...@@ -182,7 +182,7 @@ const (
) )
func newICMPEchoRequest(net string, id, seqnum, msglen int, filler []byte) []byte { func newICMPEchoRequest(net string, id, seqnum, msglen int, filler []byte) []byte {
afnet, _, _ := parseDialNetwork(net) afnet, _, _ := parseNetwork(net)
switch afnet { switch afnet {
case "ip4": case "ip4":
return newICMPv4EchoRequest(id, seqnum, msglen, filler) return newICMPv4EchoRequest(id, seqnum, msglen, filler)
......
...@@ -29,7 +29,7 @@ func ResolveIPAddr(net, addr string) (*IPAddr, error) { ...@@ -29,7 +29,7 @@ func ResolveIPAddr(net, addr string) (*IPAddr, error) {
if net == "" { // a hint wildcard for Go 1.0 undocumented behavior if net == "" { // a hint wildcard for Go 1.0 undocumented behavior
net = "ip" net = "ip"
} }
afnet, _, err := parseDialNetwork(net) afnet, _, err := parseNetwork(net)
if err != nil { if err != nil {
return nil, err return nil, err
} }
......
...@@ -166,7 +166,7 @@ func DialIP(netProto string, laddr, raddr *IPAddr) (*IPConn, error) { ...@@ -166,7 +166,7 @@ func DialIP(netProto string, laddr, raddr *IPAddr) (*IPConn, error) {
} }
func dialIP(netProto string, laddr, raddr *IPAddr, deadline time.Time) (*IPConn, error) { func dialIP(netProto string, laddr, raddr *IPAddr, deadline time.Time) (*IPConn, error) {
net, proto, err := parseDialNetwork(netProto) net, proto, err := parseNetwork(netProto)
if err != nil { if err != nil {
return nil, err return nil, err
} }
...@@ -190,7 +190,7 @@ func dialIP(netProto string, laddr, raddr *IPAddr, deadline time.Time) (*IPConn, ...@@ -190,7 +190,7 @@ func dialIP(netProto string, laddr, raddr *IPAddr, deadline time.Time) (*IPConn,
// and WriteTo methods can be used to receive and send IP // and WriteTo methods can be used to receive and send IP
// packets with per-packet addressing. // packets with per-packet addressing.
func ListenIP(netProto string, laddr *IPAddr) (*IPConn, error) { func ListenIP(netProto string, laddr *IPAddr) (*IPConn, error) {
net, proto, err := parseDialNetwork(netProto) net, proto, err := parseNetwork(netProto)
if err != nil { if err != nil {
return nil, err return nil, err
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment