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