github.com/mysteriumnetwork/node@v0.0.0-20240516044423-365054f76801/nat/event/sender.go (about) 1 /* 2 * Copyright (C) 2019 The "MysteriumNetwork/node" Authors. 3 * 4 * This program is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation, either version 3 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 package event 19 20 import ( 21 "github.com/mysteriumnetwork/node/eventbus" 22 "github.com/rs/zerolog/log" 23 ) 24 25 // Sender allows subscribing to NAT events and sends them to server 26 type Sender struct { 27 metricsSender metricsSender 28 ipResolver ipResolver 29 gatewayLoader func() []map[string]string 30 lastIp string 31 lastEvent *Event 32 } 33 34 type metricsSender interface { 35 SendNATMappingSuccessEvent(id, stage string, gateways []map[string]string) 36 SendNATMappingFailEvent(id, stage string, gateways []map[string]string, err error) 37 } 38 39 type ipResolver func() (string, error) 40 41 // NewSender returns a new instance of events sender 42 func NewSender(metricsSender metricsSender, ipResolver ipResolver, gatewayLoader func() []map[string]string) *Sender { 43 return &Sender{ 44 metricsSender: metricsSender, 45 ipResolver: ipResolver, 46 lastIp: "", 47 gatewayLoader: gatewayLoader, 48 } 49 } 50 51 // Subscribe subscribes to relevant events of event bus. 52 func (es *Sender) Subscribe(bus eventbus.Subscriber) error { 53 return bus.Subscribe(AppTopicTraversal, es.consumeNATEvent) 54 } 55 56 // consumeNATEvent sends received event to server 57 func (es *Sender) consumeNATEvent(event Event) { 58 publicIP, err := es.ipResolver() 59 if err != nil { 60 log.Warn().Err(err).Msg("Resolving public IP failed") 61 return 62 } 63 64 if publicIP == es.lastIp && es.matchesLastEvent(event) { 65 return 66 } 67 68 es.sendNATEvent(event) 69 70 es.lastIp = publicIP 71 es.lastEvent = &event 72 } 73 74 func (es *Sender) sendNATEvent(event Event) { 75 if event.Successful { 76 es.metricsSender.SendNATMappingSuccessEvent(event.ID, event.Stage, es.gatewayLoader()) 77 } else { 78 es.metricsSender.SendNATMappingFailEvent(event.ID, event.Stage, es.gatewayLoader(), event.Error) 79 } 80 } 81 82 func (es *Sender) matchesLastEvent(event Event) bool { 83 if es.lastEvent == nil { 84 return false 85 } 86 87 return event.Successful == es.lastEvent.Successful && event.Stage == es.lastEvent.Stage 88 }