server.go 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. package server
  2. import (
  3. "context"
  4. "fmt"
  5. "log"
  6. "net"
  7. "time"
  8. "github.com/gravitl/netmaker/nm-proxy/common"
  9. "github.com/gravitl/netmaker/nm-proxy/packet"
  10. )
  11. var (
  12. NmProxyServer = &ProxyServer{}
  13. )
  14. const (
  15. defaultBodySize = 10000
  16. defaultPort = common.NmProxyPort
  17. )
  18. type Config struct {
  19. Port int
  20. BodySize int
  21. IsRelay bool
  22. Addr net.Addr
  23. }
  24. type ProxyServer struct {
  25. Config Config
  26. Server *net.UDPConn
  27. }
  28. // Proxy.Listen - begins listening for packets
  29. func (p *ProxyServer) Listen(ctx context.Context) {
  30. // Buffer with indicated body size
  31. buffer := make([]byte, 1532)
  32. for {
  33. select {
  34. case <-ctx.Done():
  35. log.Println("--------->### Shutting down Proxy.....")
  36. // clean up proxy connections
  37. for iface, peers := range common.WgIFaceMap {
  38. log.Println("########------------> CLEANING UP: ", iface)
  39. for _, peerI := range peers {
  40. peerI.Proxy.Cancel()
  41. }
  42. }
  43. // close server connection
  44. NmProxyServer.Server.Close()
  45. return
  46. default:
  47. // Read Packet
  48. n, source, err := p.Server.ReadFromUDP(buffer)
  49. if err != nil { // in future log errors?
  50. log.Println("RECV ERROR: ", err)
  51. continue
  52. }
  53. var srcPeerKeyHash, dstPeerKeyHash string
  54. n, srcPeerKeyHash, dstPeerKeyHash = packet.ExtractInfo(buffer, n)
  55. //log.Printf("--------> RECV PKT [DSTPORT: %d], [SRCKEYHASH: %s], SourceIP: [%s] \n", localWgPort, srcPeerKeyHash, source.IP.String())
  56. if _, ok := common.WgIfaceKeyMap[dstPeerKeyHash]; !ok {
  57. if common.IsIngressGateway {
  58. log.Println("----> fowarding PKT to EXT client...")
  59. if val, ok := common.PeerKeyHashMap[dstPeerKeyHash]; ok && val.IsAttachedExtClient {
  60. log.Printf("-------->Forwarding the pkt to extClient [ SourceIP: %s ], [ SourceKeyHash: %s ], [ DstIP: %s ], [ DstHashKey: %s ] \n",
  61. source.String(), srcPeerKeyHash, val.Endpoint.String(), dstPeerKeyHash)
  62. _, err = NmProxyServer.Server.WriteToUDP(buffer[:n+32], val.Endpoint)
  63. if err != nil {
  64. log.Println("Failed to send to remote: ", err)
  65. }
  66. continue
  67. }
  68. }
  69. if common.IsRelay {
  70. log.Println("----------> Relaying######")
  71. // check for routing map and forward to right proxy
  72. if remoteMap, ok := common.RelayPeerMap[srcPeerKeyHash]; ok {
  73. if conf, ok := remoteMap[dstPeerKeyHash]; ok {
  74. log.Printf("--------> Relaying PKT [ SourceIP: %s:%d ], [ SourceKeyHash: %s ], [ DstIP: %s:%d ], [ DstHashKey: %s ] \n",
  75. source.IP.String(), source.Port, srcPeerKeyHash, conf.Endpoint.String(), conf.Endpoint.Port, dstPeerKeyHash)
  76. _, err = NmProxyServer.Server.WriteToUDP(buffer[:n+32], conf.Endpoint)
  77. if err != nil {
  78. log.Println("Failed to send to remote: ", err)
  79. }
  80. continue
  81. }
  82. } else {
  83. if remoteMap, ok := common.RelayPeerMap[dstPeerKeyHash]; ok {
  84. if conf, ok := remoteMap[dstPeerKeyHash]; ok {
  85. log.Printf("--------> Relaying BACK TO RELAYED NODE PKT [ SourceIP: %s ], [ SourceKeyHash: %s ], [ DstIP: %s ], [ DstHashKey: %s ] \n",
  86. source.String(), srcPeerKeyHash, conf.Endpoint.String(), dstPeerKeyHash)
  87. _, err = NmProxyServer.Server.WriteToUDP(buffer[:n+32], conf.Endpoint)
  88. if err != nil {
  89. log.Println("Failed to send to remote: ", err)
  90. }
  91. continue
  92. }
  93. }
  94. }
  95. }
  96. }
  97. if peerInfo, ok := common.PeerKeyHashMap[srcPeerKeyHash]; ok {
  98. if peers, ok := common.WgIFaceMap[peerInfo.Interface]; ok {
  99. if peerI, ok := peers[peerInfo.PeerKey]; ok {
  100. log.Printf("PROXING TO LOCAL!!!---> %s <<<< %s <<<<<<<< %s [[ RECV PKT [SRCKEYHASH: %s], [DSTKEYHASH: %s], SourceIP: [%s] ]]\n",
  101. peerI.Proxy.LocalConn.RemoteAddr(), peerI.Proxy.LocalConn.LocalAddr(),
  102. fmt.Sprintf("%s:%d", source.IP.String(), source.Port), srcPeerKeyHash, dstPeerKeyHash, source.IP.String())
  103. _, err = peerI.Proxy.LocalConn.Write(buffer[:n])
  104. if err != nil {
  105. log.Println("Failed to proxy to Wg local interface: ", err)
  106. continue
  107. }
  108. }
  109. }
  110. }
  111. }
  112. }
  113. }
  114. // Create - creats a proxy listener
  115. // port - port for proxy to listen on localhost
  116. // bodySize - default 10000, leave 0 to use default
  117. // addr - the address for proxy to listen on
  118. // forwards - indicate address to forward to, {"<address:port>",...} format
  119. func (p *ProxyServer) CreateProxyServer(port, bodySize int, addr string) (err error) {
  120. if p == nil {
  121. p = &ProxyServer{}
  122. }
  123. p.Config.Port = port
  124. p.Config.BodySize = bodySize
  125. p.setDefaults()
  126. p.Server, err = net.ListenUDP("udp", &net.UDPAddr{
  127. Port: p.Config.Port,
  128. IP: net.ParseIP(addr),
  129. })
  130. return
  131. }
  132. func (p *ProxyServer) KeepAlive(ip string, port int) {
  133. for {
  134. _, _ = p.Server.WriteToUDP([]byte("hello-proxy"), &net.UDPAddr{
  135. IP: net.ParseIP(ip),
  136. Port: port,
  137. })
  138. //log.Println("Sending MSg: ", ip, port, err)
  139. time.Sleep(time.Second * 5)
  140. }
  141. }
  142. // Proxy.setDefaults - sets all defaults of proxy listener
  143. func (p *ProxyServer) setDefaults() {
  144. p.setDefaultBodySize()
  145. p.setDefaultPort()
  146. }
  147. // Proxy.setDefaultPort - sets default port of Proxy listener if 0
  148. func (p *ProxyServer) setDefaultPort() {
  149. if p.Config.Port == 0 {
  150. p.Config.Port = defaultPort
  151. }
  152. }
  153. // Proxy.setDefaultBodySize - sets default body size of Proxy listener if 0
  154. func (p *ProxyServer) setDefaultBodySize() {
  155. if p.Config.BodySize == 0 {
  156. p.Config.BodySize = defaultBodySize
  157. }
  158. }