github.com/mysteriumnetwork/node@v0.0.0-20240516044423-365054f76801/p2p/nat/check.go (about) 1 /* 2 * Copyright (C) 2021 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 nat 19 20 import ( 21 "context" 22 "fmt" 23 "strings" 24 "sync" 25 "time" 26 27 "github.com/rs/zerolog/log" 28 29 "github.com/mysteriumnetwork/node/config" 30 "github.com/mysteriumnetwork/node/core/port" 31 ) 32 33 const ( 34 reqTimeout = 2 * time.Second 35 totalTimeout = 5 * time.Second 36 ) 37 38 type checkResp struct { 39 ok bool 40 err error 41 } 42 43 func checkAllPorts(ports []int) error { 44 var addresses []string 45 46 for _, address := range strings.Split(config.GetString(config.FlagPortCheckServers), ",") { 47 address = strings.TrimSpace(address) 48 if address != "" { 49 addresses = append(addresses, address) 50 } 51 } 52 53 var wg sync.WaitGroup 54 55 wg.Add(len(ports)) 56 57 ctx, cancel := context.WithTimeout(context.Background(), totalTimeout) 58 defer cancel() 59 60 ch := make(chan checkResp, len(ports)) 61 62 for _, p := range ports { 63 go func(p int) { 64 defer wg.Done() 65 66 ok, err := port.GloballyReachable(ctx, port.Port(p), addresses, reqTimeout) 67 ch <- checkResp{ 68 ok: ok, 69 err: err, 70 } 71 }(p) 72 } 73 74 wg.Wait() 75 close(ch) 76 77 for resp := range ch { 78 if !resp.ok || resp.err != nil { 79 return fmt.Errorf("local port not reachable: %w", resp.err) 80 } 81 } 82 83 log.Debug().Msgf("All ports %v are reachable", ports) 84 85 return nil 86 }