2
0

relay.go 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. package mq
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "net"
  6. "github.com/gravitl/netmaker/logger"
  7. "github.com/gravitl/netmaker/logic"
  8. "github.com/gravitl/netmaker/models"
  9. "github.com/gravitl/netmaker/servercfg"
  10. "golang.zx2c4.com/wireguard/wgctrl/wgtypes"
  11. )
  12. // PubPeerUpdate publishes a peer update to the client
  13. // relay is set to a newly created relay node or nil for other peer updates
  14. func PubPeerUpdate(client, relay *models.Client, peers []models.Client) {
  15. p := models.PeerAction{
  16. Action: models.UpdatePeer,
  17. }
  18. if client.Node.IsRelay {
  19. pubRelayUpdate(client, peers)
  20. return
  21. }
  22. if relay != nil {
  23. if client.Node.RelayedBy == relay.Node.ID.String() {
  24. pubRelayedUpdate(client, relay, peers)
  25. return
  26. }
  27. }
  28. for _, peer := range peers {
  29. if client.Host.ID == peer.Host.ID {
  30. continue
  31. }
  32. update := wgtypes.PeerConfig{
  33. PublicKey: peer.Host.PublicKey,
  34. ReplaceAllowedIPs: true,
  35. Endpoint: &net.UDPAddr{
  36. IP: peer.Host.EndpointIP,
  37. Port: peer.Host.ListenPort,
  38. },
  39. PersistentKeepaliveInterval: &peer.Node.PersistentKeepalive,
  40. }
  41. update.AllowedIPs = append(update.AllowedIPs, logic.AddAllowedIPs(&peer)...)
  42. if relay != nil {
  43. if peer.Node.IsRelayed && peer.Node.RelayedBy == relay.Node.ID.String() {
  44. update.Remove = true
  45. }
  46. }
  47. if peer.Node.IsRelay {
  48. update.AllowedIPs = append(update.AllowedIPs, getRelayAllowedIPs(peer)...)
  49. }
  50. p.Peers = append(p.Peers, update)
  51. }
  52. data, err := json.Marshal(p)
  53. if err != nil {
  54. logger.Log(0, "marshal peer update", err.Error())
  55. return
  56. }
  57. publish(&client.Host, fmt.Sprintf("peer/host/%s/%s", client.Host.ID.String(), servercfg.GetServer()), data)
  58. }
  59. // getRelayAllowedIPs returns the list of allowedips for a given peer that is a relay
  60. func getRelayAllowedIPs(peer models.Client) []net.IPNet {
  61. var relayIPs []net.IPNet
  62. for _, relayed := range peer.Node.RelayedNodes {
  63. node, err := logic.GetNodeByID(relayed)
  64. if err != nil {
  65. logger.Log(0, "retrieve relayed node", err.Error())
  66. continue
  67. }
  68. if node.Address.IP != nil {
  69. node.Address.Mask = net.CIDRMask(32, 32)
  70. relayIPs = append(relayIPs, node.Address)
  71. }
  72. if node.Address6.IP != nil {
  73. node.Address.Mask = net.CIDRMask(128, 128)
  74. relayIPs = append(relayIPs, node.Address6)
  75. }
  76. if node.IsRelay {
  77. relayIPs = append(relayIPs, getRelayAllowedIPs(peer)...)
  78. }
  79. if node.IsEgressGateway {
  80. relayIPs = append(relayIPs, getEgressIPs(peer)...)
  81. }
  82. if node.IsIngressGateway {
  83. relayIPs = append(relayIPs, getIngressIPs(peer)...)
  84. }
  85. }
  86. return relayIPs
  87. }
  88. // getEgressIPs returns the additional allowedips (egress ranges) that need
  89. // to be included for an egress gateway peer
  90. func getEgressIPs(peer models.Client) []net.IPNet {
  91. var egressIPs []net.IPNet
  92. for _, egressRange := range peer.Node.EgressGatewayRanges {
  93. ip, cidr, err := net.ParseCIDR(egressRange)
  94. if err != nil {
  95. logger.Log(0, "parse egress range", err.Error())
  96. continue
  97. }
  98. cidr.IP = ip
  99. egressIPs = append(egressIPs, *cidr)
  100. }
  101. return egressIPs
  102. }
  103. // getIngressIPs returns the additional allowedips (ext client addresses) that need
  104. // to be included for an ingress gateway peer
  105. // TODO: add ExtraAllowedIPs
  106. func getIngressIPs(peer models.Client) []net.IPNet {
  107. var ingressIPs []net.IPNet
  108. extclients, err := logic.GetNetworkExtClients(peer.Node.Network)
  109. if err != nil {
  110. return ingressIPs
  111. }
  112. for _, ec := range extclients {
  113. if ec.IngressGatewayID == peer.Node.ID.String() {
  114. if ec.Address != "" {
  115. ip, cidr, err := net.ParseCIDR(ec.Address)
  116. if err != nil {
  117. continue
  118. }
  119. cidr.IP = ip
  120. ingressIPs = append(ingressIPs, *cidr)
  121. }
  122. if ec.Address6 != "" {
  123. ip, cidr, err := net.ParseCIDR(ec.Address6)
  124. if err != nil {
  125. continue
  126. }
  127. cidr.IP = ip
  128. ingressIPs = append(ingressIPs, *cidr)
  129. }
  130. }
  131. }
  132. return ingressIPs
  133. }
  134. // pubRelayedUpdate - publish peer update to a node (client) that is relayed by the relay
  135. func pubRelayedUpdate(client, relay *models.Client, peers []models.Client) {
  136. //verify
  137. if !logic.StringSliceContains(relay.Node.RelayedNodes, client.Node.ID.String()) {
  138. logger.Log(0, "invalid call to pubRelayed update", client.Host.Name, relay.Host.Name)
  139. return
  140. }
  141. //remove all nodes except relay
  142. p := models.PeerAction{
  143. Action: models.RemovePeer,
  144. }
  145. for _, peer := range peers {
  146. if peer.Host.ID == relay.Host.ID || peer.Host.ID == client.Host.ID {
  147. continue
  148. }
  149. update := wgtypes.PeerConfig{
  150. PublicKey: peer.Host.PublicKey,
  151. Remove: true,
  152. }
  153. p.Peers = append(p.Peers, update)
  154. }
  155. data, err := json.Marshal(p)
  156. if err != nil {
  157. logger.Log(0, "marshal peer update", err.Error())
  158. return
  159. }
  160. publish(&client.Host, fmt.Sprintf("peer/host/%s/%s", client.Host.ID.String(), servercfg.GetServer()), data)
  161. //update the relay peer
  162. p = models.PeerAction{
  163. Action: models.UpdatePeer,
  164. }
  165. update := wgtypes.PeerConfig{
  166. PublicKey: relay.Host.PublicKey,
  167. ReplaceAllowedIPs: true,
  168. Endpoint: &net.UDPAddr{
  169. IP: relay.Host.EndpointIP,
  170. Port: relay.Host.ListenPort,
  171. },
  172. PersistentKeepaliveInterval: &relay.Node.PersistentKeepalive,
  173. }
  174. if relay.Node.Address.IP != nil {
  175. relay.Node.Address.Mask = net.CIDRMask(32, 32)
  176. update.AllowedIPs = append(update.AllowedIPs, relay.Node.Address)
  177. }
  178. if relay.Node.Address6.IP != nil {
  179. relay.Node.Address6.Mask = net.CIDRMask(128, 128)
  180. update.AllowedIPs = append(update.AllowedIPs, relay.Node.Address6)
  181. }
  182. p.Peers = append(p.Peers, update)
  183. // add all other peers to allowed ips
  184. for _, peer := range peers {
  185. if peer.Host.ID == relay.Host.ID || peer.Host.ID == client.Host.ID {
  186. continue
  187. }
  188. update.AllowedIPs = append(update.AllowedIPs, logic.AddAllowedIPs(&peer)...)
  189. }
  190. p.Peers = append(p.Peers, update)
  191. data, err = json.Marshal(p)
  192. if err != nil {
  193. logger.Log(0, "marshal peer update", err.Error())
  194. return
  195. }
  196. publish(&client.Host, fmt.Sprintf("peer/host/%s/%s", client.Host.ID.String(), servercfg.GetServer()), data)
  197. }
  198. // pubRelayUpdate - publish peer update to a relay
  199. func pubRelayUpdate(client *models.Client, peers []models.Client) {
  200. if !client.Node.IsRelay {
  201. return
  202. }
  203. // add all peers to allowedips
  204. p := models.PeerAction{
  205. Action: models.UpdatePeer,
  206. }
  207. for _, peer := range peers {
  208. if peer.Host.ID == client.Host.ID {
  209. continue
  210. }
  211. update := wgtypes.PeerConfig{
  212. PublicKey: peer.Host.PublicKey,
  213. ReplaceAllowedIPs: true,
  214. Remove: false,
  215. Endpoint: &net.UDPAddr{
  216. IP: peer.Host.EndpointIP,
  217. Port: peer.Host.ListenPort,
  218. },
  219. PersistentKeepaliveInterval: &peer.Node.PersistentKeepalive,
  220. }
  221. update.AllowedIPs = append(update.AllowedIPs, logic.AddAllowedIPs(&peer)...)
  222. p.Peers = append(p.Peers, update)
  223. }
  224. data, err := json.Marshal(p)
  225. if err != nil {
  226. logger.Log(0, "marshal peer update", err.Error())
  227. return
  228. }
  229. publish(&client.Host, fmt.Sprintf("peer/host/%s/%s", client.Host.ID.String(), servercfg.GetServer()), data)
  230. }