summaryrefslogtreecommitdiff
path: root/src/pkg/net/ipsock_plan9.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/pkg/net/ipsock_plan9.go')
-rw-r--r--src/pkg/net/ipsock_plan9.go66
1 files changed, 48 insertions, 18 deletions
diff --git a/src/pkg/net/ipsock_plan9.go b/src/pkg/net/ipsock_plan9.go
index fcec4164f..94ceea31b 100644
--- a/src/pkg/net/ipsock_plan9.go
+++ b/src/pkg/net/ipsock_plan9.go
@@ -12,19 +12,45 @@ import (
"syscall"
)
+func probe(filename, query string) bool {
+ var file *file
+ var err error
+ if file, err = open(filename); err != nil {
+ return false
+ }
+
+ r := false
+ for line, ok := file.readLine(); ok && !r; line, ok = file.readLine() {
+ f := getFields(line)
+ if len(f) < 3 {
+ continue
+ }
+ for i := 0; i < len(f); i++ {
+ if query == f[i] {
+ r = true
+ break
+ }
+ }
+ }
+ file.close()
+ return r
+}
+
func probeIPv4Stack() bool {
- // TODO(mikio): implement this when Plan 9 supports IPv6-only
- // kernel.
- return true
+ return probe(netdir+"/iproute", "4i")
}
// probeIPv6Stack returns two boolean values. If the first boolean
// value is true, kernel supports basic IPv6 functionality. If the
// second boolean value is true, kernel supports IPv6 IPv4-mapping.
func probeIPv6Stack() (supportsIPv6, supportsIPv4map bool) {
- // TODO(mikio): implement this once Plan 9 gets an IPv6
- // protocol stack implementation.
- return false, false
+ // Plan 9 uses IPv6 natively, see ip(3).
+ r := probe(netdir+"/iproute", "6i")
+ v := false
+ if r {
+ v = probe(netdir+"/iproute", "4i")
+ }
+ return r, v
}
// parsePlan9Addr parses address of the form [ip!]port (e.g. 127.0.0.1!80).
@@ -34,12 +60,12 @@ func parsePlan9Addr(s string) (ip IP, iport int, err error) {
if i >= 0 {
addr = ParseIP(s[:i])
if addr == nil {
- return nil, 0, errors.New("net: parsing IP failed")
+ return nil, 0, errors.New("parsing IP failed")
}
}
p, _, ok := dtoi(s[i+1:], 0)
if !ok {
- return nil, 0, errors.New("net: parsing port failed")
+ return nil, 0, errors.New("parsing port failed")
}
if p < 0 || p > 0xFFFF {
return nil, 0, &AddrError{"invalid port", string(p)}
@@ -133,18 +159,18 @@ func dialPlan9(net string, laddr, raddr Addr) (fd *netFD, err error) {
f.Close()
return nil, &OpError{"dial", f.Name(), raddr, err}
}
- data, err := os.OpenFile("/net/"+proto+"/"+name+"/data", os.O_RDWR, 0)
+ data, err := os.OpenFile(netdir+"/"+proto+"/"+name+"/data", os.O_RDWR, 0)
if err != nil {
f.Close()
return nil, &OpError{"dial", net, raddr, err}
}
- laddr, err = readPlan9Addr(proto, "/net/"+proto+"/"+name+"/local")
+ laddr, err = readPlan9Addr(proto, netdir+"/"+proto+"/"+name+"/local")
if err != nil {
data.Close()
f.Close()
return nil, &OpError{"dial", proto, raddr, err}
}
- return newFD(proto, name, f, data, laddr, raddr), nil
+ return newFD(proto, name, f, data, laddr, raddr)
}
func listenPlan9(net string, laddr Addr) (fd *netFD, err error) {
@@ -158,20 +184,24 @@ func listenPlan9(net string, laddr Addr) (fd *netFD, err error) {
f.Close()
return nil, &OpError{"announce", proto, laddr, err}
}
- laddr, err = readPlan9Addr(proto, "/net/"+proto+"/"+name+"/local")
+ laddr, err = readPlan9Addr(proto, netdir+"/"+proto+"/"+name+"/local")
if err != nil {
f.Close()
return nil, &OpError{Op: "listen", Net: net, Err: err}
}
- return newFD(proto, name, f, nil, laddr, nil), nil
+ return newFD(proto, name, f, nil, laddr, nil)
}
-func (l *netFD) netFD() *netFD {
- return newFD(l.proto, l.name, l.ctl, l.data, l.laddr, l.raddr)
+func (l *netFD) netFD() (*netFD, error) {
+ return newFD(l.proto, l.n, l.ctl, l.data, l.laddr, l.raddr)
}
func (l *netFD) acceptPlan9() (fd *netFD, err error) {
defer func() { netErr(err) }()
+ if err := l.readLock(); err != nil {
+ return nil, err
+ }
+ defer l.readUnlock()
f, err := os.Open(l.dir + "/listen")
if err != nil {
return nil, &OpError{"accept", l.dir + "/listen", l.laddr, err}
@@ -183,16 +213,16 @@ func (l *netFD) acceptPlan9() (fd *netFD, err error) {
return nil, &OpError{"accept", l.dir + "/listen", l.laddr, err}
}
name := string(buf[:n])
- data, err := os.OpenFile("/net/"+l.proto+"/"+name+"/data", os.O_RDWR, 0)
+ data, err := os.OpenFile(netdir+"/"+l.proto+"/"+name+"/data", os.O_RDWR, 0)
if err != nil {
f.Close()
return nil, &OpError{"accept", l.proto, l.laddr, err}
}
- raddr, err := readPlan9Addr(l.proto, "/net/"+l.proto+"/"+name+"/remote")
+ raddr, err := readPlan9Addr(l.proto, netdir+"/"+l.proto+"/"+name+"/remote")
if err != nil {
data.Close()
f.Close()
return nil, &OpError{"accept", l.proto, l.laddr, err}
}
- return newFD(l.proto, name, f, data, l.laddr, raddr), nil
+ return newFD(l.proto, name, f, data, l.laddr, raddr)
}