ipsock_plan9.go 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  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. // Internet protocol family sockets for Plan 9
  5. package net
  6. import (
  7. "errors"
  8. "os"
  9. "syscall"
  10. )
  11. func probe(filename, query string) bool {
  12. var file *file
  13. var err error
  14. if file, err = open(filename); err != nil {
  15. return false
  16. }
  17. r := false
  18. for line, ok := file.readLine(); ok && !r; line, ok = file.readLine() {
  19. f := getFields(line)
  20. if len(f) < 3 {
  21. continue
  22. }
  23. for i := 0; i < len(f); i++ {
  24. if query == f[i] {
  25. r = true
  26. break
  27. }
  28. }
  29. }
  30. file.close()
  31. return r
  32. }
  33. func probeIPv4Stack() bool {
  34. return probe(netdir+"/iproute", "4i")
  35. }
  36. // probeIPv6Stack returns two boolean values. If the first boolean
  37. // value is true, kernel supports basic IPv6 functionality. If the
  38. // second boolean value is true, kernel supports IPv6 IPv4-mapping.
  39. func probeIPv6Stack() (supportsIPv6, supportsIPv4map bool) {
  40. // Plan 9 uses IPv6 natively, see ip(3).
  41. r := probe(netdir+"/iproute", "6i")
  42. v := false
  43. if r {
  44. v = probe(netdir+"/iproute", "4i")
  45. }
  46. return r, v
  47. }
  48. // parsePlan9Addr parses address of the form [ip!]port (e.g. 127.0.0.1!80).
  49. func parsePlan9Addr(s string) (ip IP, iport int, err error) {
  50. addr := IPv4zero // address contains port only
  51. i := byteIndex(s, '!')
  52. if i >= 0 {
  53. addr = ParseIP(s[:i])
  54. if addr == nil {
  55. return nil, 0, errors.New("parsing IP failed")
  56. }
  57. }
  58. p, _, ok := dtoi(s[i+1:], 0)
  59. if !ok {
  60. return nil, 0, errors.New("parsing port failed")
  61. }
  62. if p < 0 || p > 0xFFFF {
  63. return nil, 0, &AddrError{"invalid port", string(p)}
  64. }
  65. return addr, p, nil
  66. }
  67. func readPlan9Addr(proto, filename string) (addr Addr, err error) {
  68. var buf [128]byte
  69. f, err := os.Open(filename)
  70. if err != nil {
  71. return
  72. }
  73. defer f.Close()
  74. n, err := f.Read(buf[:])
  75. if err != nil {
  76. return
  77. }
  78. ip, port, err := parsePlan9Addr(string(buf[:n]))
  79. if err != nil {
  80. return
  81. }
  82. switch proto {
  83. case "tcp":
  84. addr = &TCPAddr{IP: ip, Port: port}
  85. case "udp":
  86. addr = &UDPAddr{IP: ip, Port: port}
  87. default:
  88. return nil, errors.New("unknown protocol " + proto)
  89. }
  90. return addr, nil
  91. }
  92. func startPlan9(net string, addr Addr) (ctl *os.File, dest, proto, name string, err error) {
  93. var (
  94. ip IP
  95. port int
  96. )
  97. switch a := addr.(type) {
  98. case *TCPAddr:
  99. proto = "tcp"
  100. ip = a.IP
  101. port = a.Port
  102. case *UDPAddr:
  103. proto = "udp"
  104. ip = a.IP
  105. port = a.Port
  106. default:
  107. err = UnknownNetworkError(net)
  108. return
  109. }
  110. clone, dest, err := queryCS1(proto, ip, port)
  111. if err != nil {
  112. return
  113. }
  114. f, err := os.OpenFile(clone, os.O_RDWR, 0)
  115. if err != nil {
  116. return
  117. }
  118. var buf [16]byte
  119. n, err := f.Read(buf[:])
  120. if err != nil {
  121. f.Close()
  122. return
  123. }
  124. return f, dest, proto, string(buf[:n]), nil
  125. }
  126. func netErr(e error) {
  127. oe, ok := e.(*OpError)
  128. if !ok {
  129. return
  130. }
  131. if pe, ok := oe.Err.(*os.PathError); ok {
  132. if _, ok = pe.Err.(syscall.ErrorString); ok {
  133. oe.Err = pe.Err
  134. }
  135. }
  136. }
  137. func dialPlan9(net string, laddr, raddr Addr) (fd *netFD, err error) {
  138. defer func() { netErr(err) }()
  139. f, dest, proto, name, err := startPlan9(net, raddr)
  140. if err != nil {
  141. return nil, &OpError{"dial", net, raddr, err}
  142. }
  143. _, err = f.WriteString("connect " + dest)
  144. if err != nil {
  145. f.Close()
  146. return nil, &OpError{"dial", f.Name(), raddr, err}
  147. }
  148. data, err := os.OpenFile(netdir+"/"+proto+"/"+name+"/data", os.O_RDWR, 0)
  149. if err != nil {
  150. f.Close()
  151. return nil, &OpError{"dial", net, raddr, err}
  152. }
  153. laddr, err = readPlan9Addr(proto, netdir+"/"+proto+"/"+name+"/local")
  154. if err != nil {
  155. data.Close()
  156. f.Close()
  157. return nil, &OpError{"dial", proto, raddr, err}
  158. }
  159. return newFD(proto, name, f, data, laddr, raddr)
  160. }
  161. func listenPlan9(net string, laddr Addr) (fd *netFD, err error) {
  162. defer func() { netErr(err) }()
  163. f, dest, proto, name, err := startPlan9(net, laddr)
  164. if err != nil {
  165. return nil, &OpError{"listen", net, laddr, err}
  166. }
  167. _, err = f.WriteString("announce " + dest)
  168. if err != nil {
  169. f.Close()
  170. return nil, &OpError{"announce", proto, laddr, err}
  171. }
  172. laddr, err = readPlan9Addr(proto, netdir+"/"+proto+"/"+name+"/local")
  173. if err != nil {
  174. f.Close()
  175. return nil, &OpError{Op: "listen", Net: net, Err: err}
  176. }
  177. return newFD(proto, name, f, nil, laddr, nil)
  178. }
  179. func (l *netFD) netFD() (*netFD, error) {
  180. return newFD(l.proto, l.n, l.ctl, l.data, l.laddr, l.raddr)
  181. }
  182. func (l *netFD) acceptPlan9() (fd *netFD, err error) {
  183. defer func() { netErr(err) }()
  184. if err := l.readLock(); err != nil {
  185. return nil, err
  186. }
  187. defer l.readUnlock()
  188. f, err := os.Open(l.dir + "/listen")
  189. if err != nil {
  190. return nil, &OpError{"accept", l.dir + "/listen", l.laddr, err}
  191. }
  192. var buf [16]byte
  193. n, err := f.Read(buf[:])
  194. if err != nil {
  195. f.Close()
  196. return nil, &OpError{"accept", l.dir + "/listen", l.laddr, err}
  197. }
  198. name := string(buf[:n])
  199. data, err := os.OpenFile(netdir+"/"+l.proto+"/"+name+"/data", os.O_RDWR, 0)
  200. if err != nil {
  201. f.Close()
  202. return nil, &OpError{"accept", l.proto, l.laddr, err}
  203. }
  204. raddr, err := readPlan9Addr(l.proto, netdir+"/"+l.proto+"/"+name+"/remote")
  205. if err != nil {
  206. data.Close()
  207. f.Close()
  208. return nil, &OpError{"accept", l.proto, l.laddr, err}
  209. }
  210. return newFD(l.proto, name, f, data, l.laddr, raddr)
  211. }