iprawsock.go 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. // Copyright 2010 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. "syscall"
  8. )
  9. // BUG(mikio): On every POSIX platform, reads from the "ip4" network
  10. // using the ReadFrom or ReadFromIP method might not return a complete
  11. // IPv4 packet, including its header, even if there is space
  12. // available. This can occur even in cases where Read or ReadMsgIP
  13. // could return a complete packet. For this reason, it is recommended
  14. // that you do not use these methods if it is important to receive a
  15. // full packet.
  16. //
  17. // The Go 1 compatibility guidelines make it impossible for us to
  18. // change the behavior of these methods; use Read or ReadMsgIP
  19. // instead.
  20. // BUG(mikio): On JS and Plan 9, methods and functions related
  21. // to IPConn are not implemented.
  22. // BUG(mikio): On Windows, the File method of IPConn is not
  23. // implemented.
  24. // IPAddr represents the address of an IP end point.
  25. type IPAddr struct {
  26. IP IP
  27. Zone string // IPv6 scoped addressing zone
  28. }
  29. // Network returns the address's network name, "ip".
  30. func (a *IPAddr) Network() string { return "ip" }
  31. func (a *IPAddr) String() string {
  32. if a == nil {
  33. return "<nil>"
  34. }
  35. ip := ipEmptyString(a.IP)
  36. if a.Zone != "" {
  37. return ip + "%" + a.Zone
  38. }
  39. return ip
  40. }
  41. func (a *IPAddr) isWildcard() bool {
  42. if a == nil || a.IP == nil {
  43. return true
  44. }
  45. return a.IP.IsUnspecified()
  46. }
  47. func (a *IPAddr) opAddr() Addr {
  48. if a == nil {
  49. return nil
  50. }
  51. return a
  52. }
  53. // ResolveIPAddr returns an address of IP end point.
  54. //
  55. // The network must be an IP network name.
  56. //
  57. // If the host in the address parameter is not a literal IP address,
  58. // ResolveIPAddr resolves the address to an address of IP end point.
  59. // Otherwise, it parses the address as a literal IP address.
  60. // The address parameter can use a host name, but this is not
  61. // recommended, because it will return at most one of the host name's
  62. // IP addresses.
  63. //
  64. // See func Dial for a description of the network and address
  65. // parameters.
  66. func ResolveIPAddr(network, address string) (*IPAddr, error) {
  67. if network == "" { // a hint wildcard for Go 1.0 undocumented behavior
  68. network = "ip"
  69. }
  70. afnet, _, err := parseNetwork(context.Background(), network, false)
  71. if err != nil {
  72. return nil, err
  73. }
  74. switch afnet {
  75. case "ip", "ip4", "ip6":
  76. default:
  77. return nil, UnknownNetworkError(network)
  78. }
  79. addrs, err := DefaultResolver.internetAddrList(context.Background(), afnet, address)
  80. if err != nil {
  81. return nil, err
  82. }
  83. return addrs.forResolve(network, address).(*IPAddr), nil
  84. }
  85. // IPConn is the implementation of the Conn and PacketConn interfaces
  86. // for IP network connections.
  87. type IPConn struct {
  88. conn
  89. }
  90. // SyscallConn returns a raw network connection.
  91. // This implements the syscall.Conn interface.
  92. func (c *IPConn) SyscallConn() (syscall.RawConn, error) {
  93. if !c.ok() {
  94. return nil, syscall.EINVAL
  95. }
  96. return newRawConn(c.fd)
  97. }
  98. // ReadFromIP acts like ReadFrom but returns an IPAddr.
  99. func (c *IPConn) ReadFromIP(b []byte) (int, *IPAddr, error) {
  100. if !c.ok() {
  101. return 0, nil, syscall.EINVAL
  102. }
  103. n, addr, err := c.readFrom(b)
  104. if err != nil {
  105. err = &OpError{Op: "read", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
  106. }
  107. return n, addr, err
  108. }
  109. // ReadFrom implements the PacketConn ReadFrom method.
  110. func (c *IPConn) ReadFrom(b []byte) (int, Addr, error) {
  111. if !c.ok() {
  112. return 0, nil, syscall.EINVAL
  113. }
  114. n, addr, err := c.readFrom(b)
  115. if err != nil {
  116. err = &OpError{Op: "read", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
  117. }
  118. if addr == nil {
  119. return n, nil, err
  120. }
  121. return n, addr, err
  122. }
  123. // ReadMsgIP reads a message from c, copying the payload into b and
  124. // the associated out-of-band data into oob. It returns the number of
  125. // bytes copied into b, the number of bytes copied into oob, the flags
  126. // that were set on the message and the source address of the message.
  127. //
  128. // The packages golang.org/x/net/ipv4 and golang.org/x/net/ipv6 can be
  129. // used to manipulate IP-level socket options in oob.
  130. func (c *IPConn) ReadMsgIP(b, oob []byte) (n, oobn, flags int, addr *IPAddr, err error) {
  131. if !c.ok() {
  132. return 0, 0, 0, nil, syscall.EINVAL
  133. }
  134. n, oobn, flags, addr, err = c.readMsg(b, oob)
  135. if err != nil {
  136. err = &OpError{Op: "read", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
  137. }
  138. return
  139. }
  140. // WriteToIP acts like WriteTo but takes an IPAddr.
  141. func (c *IPConn) WriteToIP(b []byte, addr *IPAddr) (int, error) {
  142. if !c.ok() {
  143. return 0, syscall.EINVAL
  144. }
  145. n, err := c.writeTo(b, addr)
  146. if err != nil {
  147. err = &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr.opAddr(), Err: err}
  148. }
  149. return n, err
  150. }
  151. // WriteTo implements the PacketConn WriteTo method.
  152. func (c *IPConn) WriteTo(b []byte, addr Addr) (int, error) {
  153. if !c.ok() {
  154. return 0, syscall.EINVAL
  155. }
  156. a, ok := addr.(*IPAddr)
  157. if !ok {
  158. return 0, &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr, Err: syscall.EINVAL}
  159. }
  160. n, err := c.writeTo(b, a)
  161. if err != nil {
  162. err = &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: a.opAddr(), Err: err}
  163. }
  164. return n, err
  165. }
  166. // WriteMsgIP writes a message to addr via c, copying the payload from
  167. // b and the associated out-of-band data from oob. It returns the
  168. // number of payload and out-of-band bytes written.
  169. //
  170. // The packages golang.org/x/net/ipv4 and golang.org/x/net/ipv6 can be
  171. // used to manipulate IP-level socket options in oob.
  172. func (c *IPConn) WriteMsgIP(b, oob []byte, addr *IPAddr) (n, oobn int, err error) {
  173. if !c.ok() {
  174. return 0, 0, syscall.EINVAL
  175. }
  176. n, oobn, err = c.writeMsg(b, oob, addr)
  177. if err != nil {
  178. err = &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr.opAddr(), Err: err}
  179. }
  180. return
  181. }
  182. func newIPConn(fd *netFD) *IPConn { return &IPConn{conn{fd}} }
  183. // DialIP acts like Dial for IP networks.
  184. //
  185. // The network must be an IP network name; see func Dial for details.
  186. //
  187. // If laddr is nil, a local address is automatically chosen.
  188. // If the IP field of raddr is nil or an unspecified IP address, the
  189. // local system is assumed.
  190. func DialIP(network string, laddr, raddr *IPAddr) (*IPConn, error) {
  191. if raddr == nil {
  192. return nil, &OpError{Op: "dial", Net: network, Source: laddr.opAddr(), Addr: nil, Err: errMissingAddress}
  193. }
  194. sd := &sysDialer{network: network, address: raddr.String()}
  195. c, err := sd.dialIP(context.Background(), laddr, raddr)
  196. if err != nil {
  197. return nil, &OpError{Op: "dial", Net: network, Source: laddr.opAddr(), Addr: raddr.opAddr(), Err: err}
  198. }
  199. return c, nil
  200. }
  201. // ListenIP acts like ListenPacket for IP networks.
  202. //
  203. // The network must be an IP network name; see func Dial for details.
  204. //
  205. // If the IP field of laddr is nil or an unspecified IP address,
  206. // ListenIP listens on all available IP addresses of the local system
  207. // except multicast IP addresses.
  208. func ListenIP(network string, laddr *IPAddr) (*IPConn, error) {
  209. if laddr == nil {
  210. laddr = &IPAddr{}
  211. }
  212. sl := &sysListener{network: network, address: laddr.String()}
  213. c, err := sl.listenIP(context.Background(), laddr)
  214. if err != nil {
  215. return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: laddr.opAddr(), Err: err}
  216. }
  217. return c, nil
  218. }