lkcp9_readloop_linux.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. // Copyright © 2015 Daniel Fu <daniel820313@gmail.com>.
  2. // Copyright © 2019 Loki 'l0k18' Verloren <stalker.loki@protonmail.ch>.
  3. // Copyright © 2020 Gridfinity, LLC. <admin@gridfinity.com>.
  4. // Copyright © 2020 Jeffrey H. Johnson <jeff@gridfinity.com>.
  5. //
  6. // All rights reserved.
  7. //
  8. // All use of this code is governed by the MIT license.
  9. // The complete license is available in the LICENSE file.
  10. // +build linux
  11. package lkcp9 // import "go.gridfinity.dev/lkcp9"
  12. import (
  13. "net"
  14. "sync/atomic"
  15. "golang.org/x/net/ipv4"
  16. "golang.org/x/net/ipv6"
  17. )
  18. const (
  19. batchSize = 16
  20. )
  21. func (
  22. s *UDPSession,
  23. ) readLoop() {
  24. addr, _ := net.ResolveUDPAddr(
  25. "udp",
  26. s.conn.LocalAddr().String(),
  27. )
  28. if addr.IP.To4() != nil {
  29. s.readLoopIPv4()
  30. } else {
  31. s.readLoopIPv6()
  32. }
  33. }
  34. func (
  35. s *UDPSession,
  36. ) readLoopIPv6() {
  37. var src string
  38. msgs := make(
  39. []ipv6.Message,
  40. batchSize,
  41. )
  42. for k := range msgs {
  43. msgs[k].Buffers = [][]byte{
  44. make(
  45. []byte,
  46. KcpMtuLimit),
  47. }
  48. }
  49. conn := ipv6.NewPacketConn(
  50. s.conn,
  51. )
  52. for {
  53. if count, err := conn.ReadBatch(
  54. msgs,
  55. 0,
  56. ); err == nil {
  57. for i := 0; i < count; i++ {
  58. msg := &msgs[i]
  59. if src == "" {
  60. src = msg.Addr.String()
  61. } else if msg.Addr.String() != src {
  62. atomic.AddUint64(
  63. &DefaultSnsi.KcpPreInputErrors,
  64. 1,
  65. )
  66. continue
  67. }
  68. if msg.N < s.headerSize+IKCP_OVERHEAD {
  69. atomic.AddUint64(
  70. &DefaultSnsi.KcpInputErrors,
  71. 1,
  72. )
  73. continue
  74. }
  75. s.packetInput(
  76. msg.Buffers[0][:msg.N],
  77. )
  78. }
  79. } else {
  80. s.chReadError <- err
  81. return
  82. }
  83. }
  84. }
  85. func (
  86. s *UDPSession,
  87. ) readLoopIPv4() {
  88. var src string
  89. msgs := make(
  90. []ipv4.Message,
  91. batchSize,
  92. )
  93. for k := range msgs {
  94. msgs[k].Buffers = [][]byte{make(
  95. []byte,
  96. KcpMtuLimit,
  97. )}
  98. }
  99. conn := ipv4.NewPacketConn(
  100. s.conn,
  101. )
  102. for {
  103. if count, err := conn.ReadBatch(
  104. msgs,
  105. 0,
  106. ); err == nil {
  107. for i := 0; i < count; i++ {
  108. msg := &msgs[i]
  109. if src == "" {
  110. src = msg.Addr.String()
  111. } else if msg.Addr.String() != src {
  112. atomic.AddUint64(
  113. &DefaultSnsi.KcpInputErrors,
  114. 1,
  115. )
  116. continue
  117. }
  118. if msg.N < s.headerSize+IKCP_OVERHEAD {
  119. atomic.AddUint64(
  120. &DefaultSnsi.KcpInputErrors,
  121. 1,
  122. )
  123. continue
  124. }
  125. s.packetInput(
  126. msg.Buffers[0][:msg.N],
  127. )
  128. }
  129. } else {
  130. s.chReadError <- err
  131. return
  132. }
  133. }
  134. }
  135. func (
  136. l *Listener,
  137. ) monitor() {
  138. addr, _ := net.ResolveUDPAddr(
  139. "udp",
  140. l.conn.LocalAddr().String(),
  141. )
  142. if addr.IP.To4() != nil {
  143. l.monitorIPv4()
  144. } else {
  145. l.monitorIPv6()
  146. }
  147. }
  148. func (
  149. l *Listener,
  150. ) monitorIPv4() {
  151. msgs := make(
  152. []ipv4.Message,
  153. batchSize,
  154. )
  155. for k := range msgs {
  156. msgs[k].Buffers = [][]byte{make(
  157. []byte,
  158. KcpMtuLimit,
  159. )}
  160. }
  161. conn := ipv4.NewPacketConn(
  162. l.conn,
  163. )
  164. for {
  165. if count, err := conn.ReadBatch(
  166. msgs,
  167. 0,
  168. ); err == nil {
  169. for i := 0; i < count; i++ {
  170. msg := &msgs[i]
  171. if msg.N >= l.headerSize+IKCP_OVERHEAD {
  172. l.packetInput(
  173. msg.Buffers[0][:msg.N],
  174. msg.Addr,
  175. )
  176. } else {
  177. atomic.AddUint64(
  178. &DefaultSnsi.KcpInputErrors,
  179. 1,
  180. )
  181. }
  182. }
  183. } else {
  184. return
  185. }
  186. }
  187. }
  188. func (
  189. l *Listener,
  190. ) monitorIPv6() {
  191. msgs := make(
  192. []ipv6.Message,
  193. batchSize,
  194. )
  195. for k := range msgs {
  196. msgs[k].Buffers = [][]byte{make(
  197. []byte,
  198. KcpMtuLimit,
  199. )}
  200. }
  201. conn := ipv4.NewPacketConn(
  202. l.conn,
  203. )
  204. for {
  205. if count, err := conn.ReadBatch(
  206. msgs,
  207. 0,
  208. ); err == nil {
  209. for i := 0; i < count; i++ {
  210. msg := &msgs[i]
  211. if msg.N >= l.headerSize+IKCP_OVERHEAD {
  212. l.packetInput(
  213. msg.Buffers[0][:msg.N],
  214. msg.Addr,
  215. )
  216. } else {
  217. atomic.AddUint64(
  218. &DefaultSnsi.KcpInputErrors,
  219. 1,
  220. )
  221. }
  222. }
  223. } else {
  224. return
  225. }
  226. }
  227. }