github.com/mysteriumnetwork/node@v0.0.0-20240516044423-365054f76801/p2p/listener.go (about) 1 /* 2 * Copyright (C) 2020 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 p2p 19 20 import ( 21 "context" 22 "fmt" 23 "net" 24 "sync" 25 "time" 26 27 nats_lib "github.com/nats-io/nats.go" 28 "github.com/rs/zerolog/log" 29 "google.golang.org/protobuf/proto" 30 31 "github.com/mysteriumnetwork/node/communication/nats" 32 "github.com/mysteriumnetwork/node/core/ip" 33 "github.com/mysteriumnetwork/node/eventbus" 34 "github.com/mysteriumnetwork/node/identity" 35 "github.com/mysteriumnetwork/node/market" 36 "github.com/mysteriumnetwork/node/nat/traversal" 37 "github.com/mysteriumnetwork/node/p2p/compat" 38 "github.com/mysteriumnetwork/node/p2p/nat" 39 "github.com/mysteriumnetwork/node/pb" 40 "github.com/mysteriumnetwork/node/trace" 41 ) 42 43 // Listener knows how to exchange p2p keys and encrypted configuration and creates ready to use p2p channels. 44 type Listener interface { 45 // Listen listens for incoming peer connections to establish new p2p channels. Establishes p2p channel and passes it 46 // to channelHandlers 47 Listen(providerID identity.Identity, serviceType string, channelHandler func(ch Channel)) (func(), error) 48 49 // GetContact returns contract which is later can be added to proposal contacts definition so consumer can 50 // know how to connect to this p2p listener. 51 GetContact() market.Contact 52 } 53 54 // NewListener creates new p2p communication listener which is used on provider side. 55 func NewListener(brokerConn nats.Connection, signer identity.SignerFactory, verifier identity.Verifier, ipResolver ip.Resolver, eventBus eventbus.EventBus) Listener { 56 return &listener{ 57 brokerConn: brokerConn, 58 pendingConfigs: map[PublicKey]p2pConnectConfig{}, 59 ipResolver: ipResolver, 60 signer: signer, 61 verifier: verifier, 62 eventBus: eventBus, 63 } 64 } 65 66 // listener implements Listener interface. 67 type listener struct { 68 eventBus eventbus.EventBus 69 brokerConn nats.Connection 70 signer identity.SignerFactory 71 verifier identity.Verifier 72 ipResolver ip.Resolver 73 74 // Keys holds pendingConfigs temporary configs for provider side since it 75 // need to handle key exchange in two steps. 76 pendingConfigs map[PublicKey]p2pConnectConfig 77 pendingConfigsMu sync.Mutex 78 } 79 80 type p2pConnectConfig struct { 81 publicIP string 82 peerPublicIP string 83 compatibility int 84 peerPorts []int 85 localPorts []int 86 publicPorts []int 87 publicKey PublicKey 88 privateKey PrivateKey 89 peerPubKey PublicKey 90 tracer *trace.Tracer 91 upnpPortsRelease func() 92 start nat.StartPorts 93 peerID identity.Identity 94 } 95 96 func (c *p2pConnectConfig) peerIP() string { 97 if c.publicIP == c.peerPublicIP { 98 // Assume that both peers are on the same network. 99 return "127.0.0.1" 100 } 101 return c.peerPublicIP 102 } 103 104 func (m *listener) GetContact() market.Contact { 105 return market.Contact{ 106 Type: ContactTypeV1, 107 Definition: ContactDefinition{BrokerAddresses: m.brokerConn.Servers()}, 108 } 109 } 110 111 // Listen listens for incoming peer connections to establish new p2p channels. Establishes p2p channel and passes it 112 // to channelHandlers. 113 func (m *listener) Listen(providerID identity.Identity, serviceType string, channelHandlers func(ch Channel)) (func(), error) { 114 configSignedSubject, err := nats.SignedSubject(m.signer(providerID), configExchangeSubject(providerID, serviceType)) 115 if err != nil { 116 return func() {}, fmt.Errorf("cannot sign config topic: %w", err) 117 } 118 119 configSub, err := m.brokerConn.Subscribe(configSignedSubject, func(msg *nats_lib.Msg) { 120 if err := m.providerStartConfigExchange(providerID, msg); err != nil { 121 log.Err(err).Msg("Could not handle initial exchange") 122 return 123 } 124 }) 125 if err != nil { 126 return func() {}, fmt.Errorf("could not get subscribe to config exchange topic: %w", err) 127 } 128 129 ackSignedSubject, err := nats.SignedSubject(m.signer(providerID), configExchangeACKSubject(providerID, serviceType)) 130 if err != nil { 131 return func() {}, fmt.Errorf("cannot sign ack topic: %w", err) 132 } 133 134 ackSub, err := m.brokerConn.Subscribe(ackSignedSubject, func(msg *nats_lib.Msg) { 135 config, err := m.providerAckConfigExchange(msg) 136 if err != nil { 137 log.Err(err).Msg("Could not handle exchange ack") 138 return 139 } 140 141 trace := config.tracer.StartStage("Provider P2P exchange ack") 142 // Send ack in separate goroutine and start pinging. 143 // It is important that provider starts sending pings first otherwise 144 // providers router can think that consumer is sending DDoS packets. 145 go func(reply string) { 146 // race condition still happens when consumer starts to ping until provider did not manage to complete required number of pings 147 // this might be provider / consumer performance dependent 148 // make sleep time dependent on pinger interval and wait for 2 ping iterations 149 // TODO: either reintroduce eventual increase of TTL on consumer or maintain some sane delay 150 dur := traversal.DefaultPingConfig().Interval.Milliseconds() * int64(len(config.localPorts)) / 2 151 log.Debug().Msgf("Delaying pings from consumer for %v ms", dur) 152 time.Sleep(time.Duration(dur) * time.Millisecond) 153 154 if err := m.brokerConn.Publish(reply, []byte("OK")); err != nil { 155 log.Err(err).Msg("Could not publish exchange ack") 156 } 157 config.tracer.EndStage(trace) 158 }(msg.Reply) 159 160 var conn1, conn2 *net.UDPConn 161 if config.start != nil { 162 traceDial := config.tracer.StartStage("Provider P2P dial (preparation)") 163 log.Debug().Msgf("Pinging consumer using ports %v:%v initial ttl: %v", config.localPorts, config.peerPorts, 1) 164 165 conns, err := config.start(context.Background(), config.peerIP(), config.peerPorts, config.localPorts) 166 if err != nil { 167 log.Err(err).Msg("Could not ping peer") 168 return 169 } 170 171 if len(conns) != requiredConnCount { 172 log.Err(err).Msg("Could not get required number of connections") 173 return 174 } 175 176 conn1 = conns[0] 177 conn2 = conns[1] 178 config.tracer.EndStage(traceDial) 179 } else { 180 traceDial := config.tracer.StartStage("Provider P2P dial (direct)") 181 log.Debug().Msg("Skipping consumer ping") 182 conn1, err = net.DialUDP("udp4", &net.UDPAddr{Port: config.localPorts[0]}, &net.UDPAddr{IP: net.ParseIP(config.peerIP()), Port: config.peerPorts[0]}) 183 if err != nil { 184 log.Err(err).Msg("Could not create UDP conn for p2p channel") 185 return 186 } 187 conn2, err = net.DialUDP("udp4", &net.UDPAddr{Port: config.localPorts[1]}, &net.UDPAddr{IP: net.ParseIP(config.peerIP()), Port: config.peerPorts[1]}) 188 if err != nil { 189 log.Err(err).Msg("Could not create UDP conn for service") 190 return 191 } 192 config.tracer.EndStage(traceDial) 193 } 194 195 traceAck := config.tracer.StartStage("Provider P2P dial ack") 196 channel, err := newChannel(conn1, config.privateKey, config.peerPubKey, config.compatibility) 197 if err != nil { 198 log.Err(err).Msg("Could not create channel") 199 return 200 } 201 channel.setTracer(config.tracer) 202 channel.setServiceConn(conn2) 203 channel.setPeerID(config.peerID) 204 channel.setUpnpPortsRelease(config.upnpPortsRelease) 205 206 channelHandlers(channel) 207 208 channel.launchReadSendLoops() 209 210 // Send handlers ready to consumer. 211 if err := m.providerChannelHandlersReady(providerID, serviceType); err != nil { 212 log.Err(err).Msg("Could not handle channel handlers ready") 213 channel.Close() 214 return 215 } 216 config.tracer.EndStage(traceAck) 217 }) 218 if err != nil { 219 if err := configSub.Unsubscribe(); err != nil { 220 log.Err(err).Msg("Failed to unsubscribe from config exchange topic") 221 } 222 return func() {}, fmt.Errorf("could not get subscribe to config exchange acknowledge topic: %w", err) 223 } 224 225 return func() { 226 if err := configSub.Unsubscribe(); err != nil { 227 log.Err(err).Msg("Failed to unsubscribe from config exchange topic") 228 } 229 if err := ackSub.Unsubscribe(); err != nil { 230 log.Err(err).Msg("Failed to unsubscribe from config exchange acknowledge topic") 231 } 232 }, nil 233 } 234 235 func (m *listener) providerStartConfigExchange(providerID identity.Identity, msg *nats_lib.Msg) error { 236 tracer := trace.NewTracer("Provider whole Connect") 237 238 trace := tracer.StartStage("Provider P2P exchange") 239 defer tracer.EndStage(trace) 240 241 pubKey, privateKey, err := GenerateKey() 242 if err != nil { 243 return fmt.Errorf("could not generate provider p2p keys: %w", err) 244 } 245 246 // Get initial peer exchange with it's public key. 247 signedMsg, peerID, err := unpackSignedMsg(m.verifier, msg.Data) 248 if err != nil { 249 return fmt.Errorf("could not unpack signed msg: %w", err) 250 } 251 var peerExchangeMsg pb.P2PConfigExchangeMsg 252 if err := proto.Unmarshal(signedMsg.Data, &peerExchangeMsg); err != nil { 253 return err 254 } 255 peerPubKey, err := DecodePublicKey(peerExchangeMsg.PublicKey) 256 if err != nil { 257 return err 258 } 259 log.Debug().Msgf("Received consumer public key %s", peerPubKey.Hex()) 260 261 publicIP, localPorts, portsRelease, start, err := m.prepareLocalPorts(providerID.Address, tracer) 262 if err != nil { 263 return fmt.Errorf("could not prepare ports: %w", err) 264 } 265 266 p2pConnConfig := p2pConnectConfig{ 267 publicIP: publicIP, 268 localPorts: localPorts, 269 publicPorts: stunPorts(providerID, m.eventBus, localPorts...), 270 publicKey: pubKey, 271 privateKey: privateKey, 272 peerPubKey: peerPubKey, 273 tracer: tracer, 274 upnpPortsRelease: portsRelease, 275 peerPublicIP: "", 276 peerPorts: nil, 277 start: start, 278 peerID: peerID, 279 } 280 m.setPendingConfig(p2pConnConfig) 281 282 config := pb.P2PConnectConfig{ 283 PublicIP: publicIP, 284 Ports: intToInt32Slice(p2pConnConfig.publicPorts), 285 Compatibility: compat.Compatibility, 286 } 287 configCiphertext, err := encryptConnConfigMsg(&config, privateKey, peerPubKey) 288 if err != nil { 289 return fmt.Errorf("could not encrypt config msg: %w", err) 290 } 291 exchangeMsg := pb.P2PConfigExchangeMsg{ 292 PublicKey: pubKey.Hex(), 293 ConfigCiphertext: configCiphertext, 294 } 295 log.Debug().Msgf("Sending reply with public key %s and encrypted config to consumer", exchangeMsg.PublicKey) 296 packedMsg, err := packSignedMsg(m.signer, providerID, &exchangeMsg) 297 if err != nil { 298 return fmt.Errorf("could not pack signed message: %w", err) 299 } 300 err = m.brokerConn.Publish(msg.Reply, packedMsg) 301 if err != nil { 302 return fmt.Errorf("could not publish message via broker: %w", err) 303 } 304 return nil 305 } 306 307 // prepareLocalPorts acquires ports for p2p connections. It tries to acquire only 308 // required ports count for actual p2p and service connections and fallback to 309 // acquiring extra ports for nat pinger if provider is behind nat, port mapping failed 310 // and no manual port forwarding is enabled. 311 func (m *listener) prepareLocalPorts(id string, tracer *trace.Tracer) (string, []int, func(), nat.StartPorts, error) { 312 trace := tracer.StartStage("Provider P2P exchange (ports)") 313 defer tracer.EndStage(trace) 314 315 publicIP, err := m.ipResolver.GetPublicIP() 316 if err != nil { 317 return "", nil, nil, nil, fmt.Errorf("could not get public IP: %w", err) 318 } 319 320 for _, p := range nat.OrderedPortProviders() { 321 ports, release, start, err := p.Provider.PreparePorts() 322 if err == nil { 323 m.eventBus.Publish(nat.AppTopicNATTraversalMethod, nat.NATTraversalMethod{ 324 Identity: id, 325 Method: p.Method, 326 Success: true, 327 }) 328 return publicIP, ports, release, start, nil 329 } 330 331 m.eventBus.Publish(nat.AppTopicNATTraversalMethod, nat.NATTraversalMethod{ 332 Identity: id, 333 Method: p.Method, 334 Success: false, 335 }) 336 } 337 338 return "", nil, nil, nil, fmt.Errorf("failed to prepare local ports") 339 } 340 341 func (m *listener) providerAckConfigExchange(msg *nats_lib.Msg) (*p2pConnectConfig, error) { 342 signedMsg, peerID, err := unpackSignedMsg(m.verifier, msg.Data) 343 if err != nil { 344 return nil, fmt.Errorf("could not unpack signed msg: %w", err) 345 } 346 var peerExchangeMsg pb.P2PConfigExchangeMsg 347 if err := proto.Unmarshal(signedMsg.Data, &peerExchangeMsg); err != nil { 348 return nil, fmt.Errorf("could not unmarshal exchange msg: %w", err) 349 } 350 peerPubKey, err := DecodePublicKey(peerExchangeMsg.PublicKey) 351 if err != nil { 352 return nil, err 353 } 354 355 defer m.deletePendingConfig(peerPubKey) 356 config, ok := m.pendingConfig(peerPubKey) 357 if !ok { 358 return nil, fmt.Errorf("pending config not found for key %s", peerPubKey.Hex()) 359 } 360 if peerID != config.peerID { 361 return nil, fmt.Errorf("acknowledged config signed by unexpected identity: %s", peerID.ToCommonAddress()) 362 } 363 364 peerConfig, err := decryptConnConfigMsg(peerExchangeMsg.ConfigCiphertext, config.privateKey, peerPubKey) 365 if err != nil { 366 return nil, fmt.Errorf("could not decrypt peer conn config: %w", err) 367 } 368 369 return &p2pConnectConfig{ 370 peerPublicIP: peerConfig.PublicIP, 371 peerPorts: int32ToIntSlice(peerConfig.Ports), 372 compatibility: int(peerConfig.Compatibility), 373 localPorts: config.localPorts, 374 publicKey: config.publicKey, 375 privateKey: config.privateKey, 376 peerPubKey: config.peerPubKey, 377 publicIP: config.publicIP, 378 tracer: config.tracer, 379 upnpPortsRelease: config.upnpPortsRelease, 380 start: config.start, 381 peerID: config.peerID, 382 }, nil 383 } 384 385 func (m *listener) providerChannelHandlersReady(providerID identity.Identity, serviceType string) error { 386 handlersReadyMsg := pb.P2PChannelHandlersReady{Value: "HANDLERS READY"} 387 388 message, err := proto.Marshal(&handlersReadyMsg) 389 if err != nil { 390 return fmt.Errorf("could not marshal exchange msg: %w", err) 391 } 392 393 signedSubject, err := nats.SignedSubject(m.signer(providerID), channelHandlersReadySubject(providerID, serviceType)) 394 if err != nil { 395 return fmt.Errorf("unable to sign p2p-channel-handlers-ready subject: %w", err) 396 } 397 398 log.Debug().Msgf("Sending handlers ready message") 399 return m.brokerConn.Publish(signedSubject, message) 400 } 401 402 func (m *listener) pendingConfig(peerPubKey PublicKey) (p2pConnectConfig, bool) { 403 m.pendingConfigsMu.Lock() 404 defer m.pendingConfigsMu.Unlock() 405 config, ok := m.pendingConfigs[peerPubKey] 406 return config, ok 407 } 408 409 func (m *listener) setPendingConfig(config p2pConnectConfig) { 410 m.pendingConfigsMu.Lock() 411 defer m.pendingConfigsMu.Unlock() 412 m.pendingConfigs[config.peerPubKey] = config 413 } 414 415 func (m *listener) deletePendingConfig(peerPubKey PublicKey) { 416 m.pendingConfigsMu.Lock() 417 defer m.pendingConfigsMu.Unlock() 418 delete(m.pendingConfigs, peerPubKey) 419 }