udpsock_plan9.go 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. // Copyright 2009 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package net
  5. import (
  6. "context"
  7. "errors"
  8. "net/netip"
  9. "os"
  10. "syscall"
  11. )
  12. func (c *UDPConn) readFrom(b []byte, addr *UDPAddr) (int, *UDPAddr, error) {
  13. buf := make([]byte, udpHeaderSize+len(b))
  14. m, err := c.fd.Read(buf)
  15. if err != nil {
  16. return 0, nil, err
  17. }
  18. if m < udpHeaderSize {
  19. return 0, nil, errors.New("short read reading UDP header")
  20. }
  21. buf = buf[:m]
  22. h, buf := unmarshalUDPHeader(buf)
  23. n := copy(b, buf)
  24. *addr = UDPAddr{IP: h.raddr, Port: int(h.rport)}
  25. return n, addr, nil
  26. }
  27. func (c *UDPConn) readFromAddrPort(b []byte) (int, netip.AddrPort, error) {
  28. // TODO: optimize. The equivalent code on posix is alloc-free.
  29. buf := make([]byte, udpHeaderSize+len(b))
  30. m, err := c.fd.Read(buf)
  31. if err != nil {
  32. return 0, netip.AddrPort{}, err
  33. }
  34. if m < udpHeaderSize {
  35. return 0, netip.AddrPort{}, errors.New("short read reading UDP header")
  36. }
  37. buf = buf[:m]
  38. h, buf := unmarshalUDPHeader(buf)
  39. n := copy(b, buf)
  40. ip, _ := netip.AddrFromSlice(h.raddr)
  41. addr := netip.AddrPortFrom(ip, h.rport)
  42. return n, addr, nil
  43. }
  44. func (c *UDPConn) readMsg(b, oob []byte) (n, oobn, flags int, addr netip.AddrPort, err error) {
  45. return 0, 0, 0, netip.AddrPort{}, syscall.EPLAN9
  46. }
  47. func (c *UDPConn) writeTo(b []byte, addr *UDPAddr) (int, error) {
  48. if addr == nil {
  49. return 0, errMissingAddress
  50. }
  51. h := new(udpHeader)
  52. h.raddr = addr.IP.To16()
  53. h.laddr = c.fd.laddr.(*UDPAddr).IP.To16()
  54. h.ifcaddr = IPv6zero // ignored (receive only)
  55. h.rport = uint16(addr.Port)
  56. h.lport = uint16(c.fd.laddr.(*UDPAddr).Port)
  57. buf := make([]byte, udpHeaderSize+len(b))
  58. i := copy(buf, h.Bytes())
  59. copy(buf[i:], b)
  60. if _, err := c.fd.Write(buf); err != nil {
  61. return 0, err
  62. }
  63. return len(b), nil
  64. }
  65. func (c *UDPConn) writeToAddrPort(b []byte, addr netip.AddrPort) (int, error) {
  66. return c.writeTo(b, UDPAddrFromAddrPort(addr)) // TODO: optimize instead of allocating
  67. }
  68. func (c *UDPConn) writeMsg(b, oob []byte, addr *UDPAddr) (n, oobn int, err error) {
  69. return 0, 0, syscall.EPLAN9
  70. }
  71. func (c *UDPConn) writeMsgAddrPort(b, oob []byte, addr netip.AddrPort) (n, oobn int, err error) {
  72. return 0, 0, syscall.EPLAN9
  73. }
  74. func (sd *sysDialer) dialUDP(ctx context.Context, laddr, raddr *UDPAddr) (*UDPConn, error) {
  75. fd, err := dialPlan9(ctx, sd.network, laddr, raddr)
  76. if err != nil {
  77. return nil, err
  78. }
  79. return newUDPConn(fd), nil
  80. }
  81. const udpHeaderSize = 16*3 + 2*2
  82. type udpHeader struct {
  83. raddr, laddr, ifcaddr IP
  84. rport, lport uint16
  85. }
  86. func (h *udpHeader) Bytes() []byte {
  87. b := make([]byte, udpHeaderSize)
  88. i := 0
  89. i += copy(b[i:i+16], h.raddr)
  90. i += copy(b[i:i+16], h.laddr)
  91. i += copy(b[i:i+16], h.ifcaddr)
  92. b[i], b[i+1], i = byte(h.rport>>8), byte(h.rport), i+2
  93. b[i], b[i+1], i = byte(h.lport>>8), byte(h.lport), i+2
  94. return b
  95. }
  96. func unmarshalUDPHeader(b []byte) (*udpHeader, []byte) {
  97. h := new(udpHeader)
  98. h.raddr, b = IP(b[:16]), b[16:]
  99. h.laddr, b = IP(b[:16]), b[16:]
  100. h.ifcaddr, b = IP(b[:16]), b[16:]
  101. h.rport, b = uint16(b[0])<<8|uint16(b[1]), b[2:]
  102. h.lport, b = uint16(b[0])<<8|uint16(b[1]), b[2:]
  103. return h, b
  104. }
  105. func (sl *sysListener) listenUDP(ctx context.Context, laddr *UDPAddr) (*UDPConn, error) {
  106. l, err := listenPlan9(ctx, sl.network, laddr)
  107. if err != nil {
  108. return nil, err
  109. }
  110. _, err = l.ctl.WriteString("headers")
  111. if err != nil {
  112. return nil, err
  113. }
  114. l.data, err = os.OpenFile(l.dir+"/data", os.O_RDWR, 0)
  115. if err != nil {
  116. return nil, err
  117. }
  118. fd, err := l.netFD()
  119. return newUDPConn(fd), err
  120. }
  121. func (sl *sysListener) listenMulticastUDP(ctx context.Context, ifi *Interface, gaddr *UDPAddr) (*UDPConn, error) {
  122. // Plan 9 does not like announce command with a multicast address,
  123. // so do not specify an IP address when listening.
  124. l, err := listenPlan9(ctx, sl.network, &UDPAddr{IP: nil, Port: gaddr.Port, Zone: gaddr.Zone})
  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. var addrs []Addr
  133. if ifi != nil {
  134. addrs, err = ifi.Addrs()
  135. if err != nil {
  136. return nil, err
  137. }
  138. } else {
  139. addrs, err = InterfaceAddrs()
  140. if err != nil {
  141. return nil, err
  142. }
  143. }
  144. have4 := gaddr.IP.To4() != nil
  145. for _, addr := range addrs {
  146. if ipnet, ok := addr.(*IPNet); ok && (ipnet.IP.To4() != nil) == have4 {
  147. _, err = l.ctl.WriteString("addmulti " + ipnet.IP.String() + " " + gaddr.IP.String())
  148. if err != nil {
  149. return nil, &OpError{Op: "addmulti", Net: "", Source: nil, Addr: ipnet, Err: err}
  150. }
  151. }
  152. }
  153. l.data, err = os.OpenFile(l.dir+"/data", os.O_RDWR, 0)
  154. if err != nil {
  155. return nil, err
  156. }
  157. fd, err := l.netFD()
  158. if err != nil {
  159. return nil, err
  160. }
  161. return newUDPConn(fd), nil
  162. }