Source file
src/net/udpsock_plan9.go
Documentation: net
1
2
3
4
5 package net
6
7 import (
8 "context"
9 "errors"
10 "os"
11 "syscall"
12 )
13
14 func (c *UDPConn) readFrom(b []byte, addr *UDPAddr) (int, *UDPAddr, error) {
15 buf := make([]byte, udpHeaderSize+len(b))
16 m, err := c.fd.Read(buf)
17 if err != nil {
18 return 0, nil, err
19 }
20 if m < udpHeaderSize {
21 return 0, nil, errors.New("short read reading UDP header")
22 }
23 buf = buf[:m]
24
25 h, buf := unmarshalUDPHeader(buf)
26 n := copy(b, buf)
27 *addr = UDPAddr{IP: h.raddr, Port: int(h.rport)}
28 return n, addr, nil
29 }
30
31 func (c *UDPConn) readMsg(b, oob []byte) (n, oobn, flags int, addr *UDPAddr, err error) {
32 return 0, 0, 0, nil, syscall.EPLAN9
33 }
34
35 func (c *UDPConn) writeTo(b []byte, addr *UDPAddr) (int, error) {
36 if addr == nil {
37 return 0, errMissingAddress
38 }
39 h := new(udpHeader)
40 h.raddr = addr.IP.To16()
41 h.laddr = c.fd.laddr.(*UDPAddr).IP.To16()
42 h.ifcaddr = IPv6zero
43 h.rport = uint16(addr.Port)
44 h.lport = uint16(c.fd.laddr.(*UDPAddr).Port)
45
46 buf := make([]byte, udpHeaderSize+len(b))
47 i := copy(buf, h.Bytes())
48 copy(buf[i:], b)
49 if _, err := c.fd.Write(buf); err != nil {
50 return 0, err
51 }
52 return len(b), nil
53 }
54
55 func (c *UDPConn) writeMsg(b, oob []byte, addr *UDPAddr) (n, oobn int, err error) {
56 return 0, 0, syscall.EPLAN9
57 }
58
59 func (sd *sysDialer) dialUDP(ctx context.Context, laddr, raddr *UDPAddr) (*UDPConn, error) {
60 fd, err := dialPlan9(ctx, sd.network, laddr, raddr)
61 if err != nil {
62 return nil, err
63 }
64 return newUDPConn(fd), nil
65 }
66
67 const udpHeaderSize = 16*3 + 2*2
68
69 type udpHeader struct {
70 raddr, laddr, ifcaddr IP
71 rport, lport uint16
72 }
73
74 func (h *udpHeader) Bytes() []byte {
75 b := make([]byte, udpHeaderSize)
76 i := 0
77 i += copy(b[i:i+16], h.raddr)
78 i += copy(b[i:i+16], h.laddr)
79 i += copy(b[i:i+16], h.ifcaddr)
80 b[i], b[i+1], i = byte(h.rport>>8), byte(h.rport), i+2
81 b[i], b[i+1], i = byte(h.lport>>8), byte(h.lport), i+2
82 return b
83 }
84
85 func unmarshalUDPHeader(b []byte) (*udpHeader, []byte) {
86 h := new(udpHeader)
87 h.raddr, b = IP(b[:16]), b[16:]
88 h.laddr, b = IP(b[:16]), b[16:]
89 h.ifcaddr, b = IP(b[:16]), b[16:]
90 h.rport, b = uint16(b[0])<<8|uint16(b[1]), b[2:]
91 h.lport, b = uint16(b[0])<<8|uint16(b[1]), b[2:]
92 return h, b
93 }
94
95 func (sl *sysListener) listenUDP(ctx context.Context, laddr *UDPAddr) (*UDPConn, error) {
96 l, err := listenPlan9(ctx, sl.network, laddr)
97 if err != nil {
98 return nil, err
99 }
100 _, err = l.ctl.WriteString("headers")
101 if err != nil {
102 return nil, err
103 }
104 l.data, err = os.OpenFile(l.dir+"/data", os.O_RDWR, 0)
105 if err != nil {
106 return nil, err
107 }
108 fd, err := l.netFD()
109 return newUDPConn(fd), err
110 }
111
112 func (sl *sysListener) listenMulticastUDP(ctx context.Context, ifi *Interface, gaddr *UDPAddr) (*UDPConn, error) {
113
114
115 l, err := listenPlan9(ctx, sl.network, &UDPAddr{IP: nil, Port: gaddr.Port, Zone: gaddr.Zone})
116 if err != nil {
117 return nil, err
118 }
119 _, err = l.ctl.WriteString("headers")
120 if err != nil {
121 return nil, err
122 }
123 var addrs []Addr
124 if ifi != nil {
125 addrs, err = ifi.Addrs()
126 if err != nil {
127 return nil, err
128 }
129 } else {
130 addrs, err = InterfaceAddrs()
131 if err != nil {
132 return nil, err
133 }
134 }
135
136 have4 := gaddr.IP.To4() != nil
137 for _, addr := range addrs {
138 if ipnet, ok := addr.(*IPNet); ok && (ipnet.IP.To4() != nil) == have4 {
139 _, err = l.ctl.WriteString("addmulti " + ipnet.IP.String() + " " + gaddr.IP.String())
140 if err != nil {
141 return nil, &OpError{Op: "addmulti", Net: "", Source: nil, Addr: ipnet, Err: err}
142 }
143 }
144 }
145 l.data, err = os.OpenFile(l.dir+"/data", os.O_RDWR, 0)
146 if err != nil {
147 return nil, err
148 }
149 fd, err := l.netFD()
150 if err != nil {
151 return nil, err
152 }
153 return newUDPConn(fd), nil
154 }
155
View as plain text