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