github.com/mysteriumnetwork/node@v0.0.0-20240516044423-365054f76801/router/allow.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 router 19 20 import ( 21 "net" 22 "net/url" 23 "sync" 24 "time" 25 26 "github.com/rs/zerolog/log" 27 "golang.org/x/net/context" 28 29 "github.com/mysteriumnetwork/node/requests/resolver" 30 ) 31 32 var ( 33 // DefaultRouter contains a default router used for managing routing tables. 34 DefaultRouter Manager 35 once sync.Once 36 ) 37 38 // Manager describes a routing tables management service. 39 type Manager interface { 40 ExcludeIP(net.IP) error 41 RemoveExcludedIP(net.IP) error 42 Clean() error 43 } 44 45 func ensureRouterStarted() { 46 once.Do(func() { 47 if DefaultRouter == nil { 48 DefaultRouter = NewManager() 49 } 50 }) 51 } 52 53 // ExcludeURL adds exception to route traffic directly for specified URL (host part is usually taken). 54 func ExcludeURL(urls ...string) error { 55 ensureRouterStarted() 56 57 for _, u := range urls { 58 parsed, err := url.Parse(u) 59 if err != nil { 60 log.Error().Err(err).Msgf("Failed to parse URL: %s", u) 61 continue 62 } 63 64 addresses := resolver.FetchDNSFromCache(parsed.Hostname()) 65 if len(addresses) == 0 { 66 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) 67 defer cancel() 68 69 addresses, err = net.DefaultResolver.LookupHost(ctx, parsed.Hostname()) 70 if err != nil { 71 log.Error().Err(err).Msgf("Failed to exclude URL from routes: %s", parsed.Hostname()) 72 continue 73 } 74 } 75 76 for _, a := range addresses { 77 ipv4 := net.ParseIP(a) 78 err := DefaultRouter.ExcludeIP(ipv4) 79 log.Info().Err(err).Msgf("Excluding URL address from the routes: %s -> %s", u, ipv4) 80 } 81 } 82 83 return nil 84 } 85 86 // RemoveExcludedURL removes exception to route traffic directly for specified URL (host part is usually taken). 87 func RemoveExcludedURL(urls ...string) error { 88 ensureRouterStarted() 89 90 for _, u := range urls { 91 parsed, err := url.Parse(u) 92 if err != nil { 93 log.Error().Err(err).Msgf("Failed to parse URL: %s", u) 94 continue 95 } 96 97 addresses := resolver.FetchDNSFromCache(parsed.Hostname()) 98 if len(addresses) == 0 { 99 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) 100 defer cancel() 101 102 addresses, err = net.DefaultResolver.LookupHost(ctx, parsed.Hostname()) 103 if err != nil { 104 log.Error().Err(err).Msgf("Failed to exclude URL from routes: %s", parsed.Hostname()) 105 continue 106 } 107 } 108 109 for _, a := range addresses { 110 ipv4 := net.ParseIP(a) 111 err := DefaultRouter.RemoveExcludedIP(ipv4) 112 log.Info().Err(err).Msgf("Excluding URL address from the routes: %s -> %s", u, ipv4) 113 } 114 } 115 116 return nil 117 } 118 119 // ExcludeIP adds IP based exception to route traffic directly. 120 func ExcludeIP(ip net.IP) error { 121 ensureRouterStarted() 122 123 err := DefaultRouter.ExcludeIP(ip) 124 if err != nil { 125 log.Info().Err(err).Msgf("Excluding IP address from the routes: %s", ip) 126 } 127 128 return nil 129 } 130 131 // Clean removes all previously added routing rules. 132 func Clean() error { 133 ensureRouterStarted() 134 135 err := DefaultRouter.Clean() 136 if err != nil { 137 log.Info().Err(err).Msgf("Failed to clean") 138 } 139 140 return nil 141 } 142 143 // RemoveExcludedIP removes IP based exception to route traffic directly. 144 func RemoveExcludedIP(ip net.IP) error { 145 ensureRouterStarted() 146 147 err := DefaultRouter.RemoveExcludedIP(ip) 148 if err != nil { 149 log.Info().Err(err).Msgf("Removing excluded IP address from the routes: %s", ip) 150 } 151 152 return nil 153 }