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 @@
package net
import (
"time"
)
import "time"
func parseDialNetwork(net string) (afnet string, proto int, err error) {
func parseNetwork(net string) (afnet string, proto int, err error) {
i := last(net, ':')
if i < 0 { // no colon
switch net {
......@@ -37,29 +35,19 @@ func parseDialNetwork(net string) (afnet string, proto int, err error) {
return "", 0, UnknownNetworkError(net)
}
func resolveNetAddr(op, net, addr string, deadline time.Time) (afnet string, a Addr, err error) {
afnet, _, err = parseDialNetwork(net)
func resolveAddr(op, net, addr string, deadline time.Time) (Addr, error) {
afnet, _, err := parseNetwork(net)
if err != nil {
return "", nil, &OpError{op, net, nil, err}
return nil, &OpError{op, net, nil, err}
}
if op == "dial" && addr == "" {
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
return nil, &OpError{op, net, nil, errMissingAddress}
}
switch afnet {
case "tcp", "tcp4", "tcp6", "udp", "udp4", "udp6", "ip", "ip4", "ip6":
return resolveInternetAddr(afnet, addr, deadline)
case "unix", "unixgram", "unixpacket":
return ResolveUnixAddr(afnet, addr)
}
return nil, nil
return resolveInternetAddr(afnet, addr, deadline)
}
// Dial connects to the address addr on the network net.
......@@ -86,15 +74,15 @@ func resolveAfnetAddr(afnet, addr string, deadline time.Time) (Addr, error) {
// Dial("ip6:ospf", "::1")
//
func Dial(net, addr string) (Conn, error) {
_, addri, err := resolveNetAddr("dial", net, addr, noDeadline)
ra, err := resolveAddr("dial", net, addr, noDeadline)
if err != nil {
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) {
switch ra := addri.(type) {
func dial(net, addr string, ra Addr, deadline time.Time) (c Conn, err error) {
switch ra := ra.(type) {
case *TCPAddr:
c, err = dialTCP(net, nil, ra, deadline)
case *UDPAddr:
......@@ -132,30 +120,30 @@ func dialTimeoutRace(net, addr string, timeout time.Duration) (Conn, error) {
ch := make(chan pair, 1)
resolvedAddr := make(chan Addr, 1)
go func() {
_, addri, err := resolveNetAddr("dial", net, addr, noDeadline)
ra, err := resolveAddr("dial", net, addr, noDeadline)
if err != nil {
ch <- pair{nil, err}
return
}
resolvedAddr <- addri // in case we need it for OpError
c, err := dialAddr(net, addr, addri, noDeadline)
resolvedAddr <- ra // in case we need it for OpError
c, err := dial(net, addr, ra, noDeadline)
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.
var addri Addr
var ra Addr
select {
case a := <-resolvedAddr:
addri = a
ra = a
default:
addri = &stringAddr{net, addr}
ra = &stringAddr{net, addr}
}
err := &OpError{
Op: "dial",
Net: net,
Addr: addri,
Addr: ra,
Err: &timeoutError{},
}
return nil, err
......@@ -176,22 +164,14 @@ func (a stringAddr) String() string { return a.addr }
// The network string net must be a stream-oriented network:
// "tcp", "tcp4", "tcp6", "unix" or "unixpacket".
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 {
return nil, err
}
switch afnet {
case "tcp", "tcp4", "tcp6":
var la *TCPAddr
if a != nil {
la = a.(*TCPAddr)
}
switch la := la.(type) {
case *TCPAddr:
return ListenTCP(net, la)
case "unix", "unixpacket":
var la *UnixAddr
if a != nil {
la = a.(*UnixAddr)
}
case *UnixAddr:
return ListenUnix(net, la)
}
return nil, UnknownNetworkError(net)
......@@ -201,28 +181,16 @@ func Listen(net, laddr string) (Listener, error) {
// The network string net must be a packet-oriented network:
// "udp", "udp4", "udp6", "ip", "ip4", "ip6" or "unixgram".
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 {
return nil, err
}
switch afnet {
case "udp", "udp4", "udp6":
var la *UDPAddr
if a != nil {
la = a.(*UDPAddr)
}
switch la := la.(type) {
case *UDPAddr:
return ListenUDP(net, la)
case "ip", "ip4", "ip6":
var la *IPAddr
if a != nil {
la = a.(*IPAddr)
}
case *IPAddr:
return ListenIP(net, la)
case "unixgram":
var la *UnixAddr
if a != nil {
la = a.(*UnixAddr)
}
case *UnixAddr:
return ListenUnixgram(net, la)
}
return nil, UnknownNetworkError(net)
......
......@@ -297,11 +297,11 @@ func server(fd int) *pollServer {
func dialTimeout(net, addr string, timeout time.Duration) (Conn, error) {
deadline := time.Now().Add(timeout)
_, addri, err := resolveNetAddr("dial", net, addr, deadline)
ra, err := resolveAddr("dial", net, addr, deadline)
if err != nil {
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) {
......
......@@ -61,11 +61,11 @@ func dialTimeout(net, addr string, timeout time.Duration) (Conn, error) {
return dialTimeoutRace(net, addr, timeout)
}
deadline := time.Now().Add(timeout)
_, addri, err := resolveNetAddr("dial", net, addr, deadline)
ra, err := resolveAddr("dial", net, addr, deadline)
if err != nil {
return nil, err
}
return dialAddr(net, addr, addri, deadline)
return dial(net, addr, ra, deadline)
}
// Interface for all IO operations.
......
......@@ -182,7 +182,7 @@ const (
)
func newICMPEchoRequest(net string, id, seqnum, msglen int, filler []byte) []byte {
afnet, _, _ := parseDialNetwork(net)
afnet, _, _ := parseNetwork(net)
switch afnet {
case "ip4":
return newICMPv4EchoRequest(id, seqnum, msglen, filler)
......
......@@ -29,7 +29,7 @@ func ResolveIPAddr(net, addr string) (*IPAddr, error) {
if net == "" { // a hint wildcard for Go 1.0 undocumented behavior
net = "ip"
}
afnet, _, err := parseDialNetwork(net)
afnet, _, err := parseNetwork(net)
if err != nil {
return nil, err
}
......
......@@ -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) {
net, proto, err := parseDialNetwork(netProto)
net, proto, err := parseNetwork(netProto)
if err != nil {
return nil, err
}
......@@ -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
// packets with per-packet addressing.
func ListenIP(netProto string, laddr *IPAddr) (*IPConn, error) {
net, proto, err := parseDialNetwork(netProto)
net, proto, err := parseNetwork(netProto)
if err != nil {
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