github.com/koko1123/flow-go-1@v0.29.6/network/p2p/connection/connection_gater.go (about) 1 package connection 2 3 import ( 4 "sync" 5 6 "github.com/libp2p/go-libp2p/core/connmgr" 7 "github.com/libp2p/go-libp2p/core/control" 8 "github.com/libp2p/go-libp2p/core/network" 9 "github.com/libp2p/go-libp2p/core/peer" 10 "github.com/multiformats/go-multiaddr" 11 "github.com/rs/zerolog" 12 13 "github.com/koko1123/flow-go-1/network/p2p" 14 "github.com/koko1123/flow-go-1/utils/logging" 15 ) 16 17 var _ connmgr.ConnectionGater = (*ConnGater)(nil) 18 19 // ConnGaterOption allow the connection gater to be configured with a list of PeerFilter funcs for a specific conn gater callback. 20 // In the current implementation of the ConnGater the following callbacks can be configured with peer filters. 21 // * InterceptPeerDial - peer filters can be configured with WithOnInterceptPeerDialFilters which will allow or disallow outbound connections. 22 // * InterceptSecured - peer filters can be configured with WithOnInterceptSecuredFilters which will allow or disallow inbound connections after libP2P security handshake. 23 type ConnGaterOption func(*ConnGater) 24 25 // WithOnInterceptPeerDialFilters sets peer filters for outbound connections. 26 func WithOnInterceptPeerDialFilters(filters []p2p.PeerFilter) ConnGaterOption { 27 return func(c *ConnGater) { 28 c.onInterceptPeerDialFilters = filters 29 } 30 } 31 32 // WithOnInterceptSecuredFilters sets peer filters for inbound secured connections. 33 func WithOnInterceptSecuredFilters(filters []p2p.PeerFilter) ConnGaterOption { 34 return func(c *ConnGater) { 35 c.onInterceptSecuredFilters = filters 36 } 37 } 38 39 // ConnGater is the implementation of the libp2p connmgr.ConnectionGater interface 40 // It provides node allowlisting by libp2p peer.ID which is derived from the node public networking key 41 type ConnGater struct { 42 sync.RWMutex 43 onInterceptPeerDialFilters []p2p.PeerFilter 44 onInterceptSecuredFilters []p2p.PeerFilter 45 log zerolog.Logger 46 } 47 48 func NewConnGater(log zerolog.Logger, opts ...ConnGaterOption) *ConnGater { 49 cg := &ConnGater{ 50 log: log.With().Str("component", "connection_gater").Logger(), 51 } 52 53 for _, opt := range opts { 54 opt(cg) 55 } 56 57 return cg 58 } 59 60 // InterceptPeerDial - a callback which allows or disallows outbound connection 61 func (c *ConnGater) InterceptPeerDial(p peer.ID) bool { 62 if len(c.onInterceptPeerDialFilters) == 0 { 63 c.log.Debug(). 64 Str("peer_id", p.String()). 65 Msg("allowing outbound connection intercept peer dial has no peer filters set") 66 return true 67 } 68 69 if err := c.peerIDPassesAllFilters(p, c.onInterceptPeerDialFilters); err != nil { 70 // log the filtered outbound connection attempt 71 c.log.Warn(). 72 Err(err). 73 Str("peer_id", p.String()). 74 Msg("rejected outbound connection attempt") 75 return false 76 } 77 78 return true 79 } 80 81 // InterceptAddrDial is not used. Currently, allowlisting is only implemented by Peer IDs and not multi-addresses 82 func (c *ConnGater) InterceptAddrDial(_ peer.ID, ma multiaddr.Multiaddr) bool { 83 return true 84 } 85 86 // InterceptAccept is not used. Currently, allowlisting is only implemented by Peer IDs and not multi-addresses 87 func (c *ConnGater) InterceptAccept(cm network.ConnMultiaddrs) bool { 88 return true 89 } 90 91 // InterceptSecured a callback executed after the libp2p security handshake. It tests whether to accept or reject 92 // an inbound connection based on its peer id. 93 func (c *ConnGater) InterceptSecured(dir network.Direction, p peer.ID, addr network.ConnMultiaddrs) bool { 94 switch dir { 95 case network.DirInbound: 96 lg := c.log.With(). 97 Str("peer_id", p.String()). 98 Str("remote_address", addr.RemoteMultiaddr().String()). 99 Logger() 100 101 if len(c.onInterceptSecuredFilters) == 0 { 102 lg.Info().Msg("inbound connection established") 103 return true 104 } 105 106 if err := c.peerIDPassesAllFilters(p, c.onInterceptSecuredFilters); err != nil { 107 // log the illegal connection attempt from the remote node 108 lg.Error(). 109 Err(err). 110 Str("local_address", addr.LocalMultiaddr().String()). 111 Bool(logging.KeySuspicious, true). 112 Msg("rejected inbound connection") 113 return false 114 } 115 116 lg.Info().Msg("inbound connection established") 117 return true 118 default: 119 // outbound connection should have been already blocked before this call 120 return true 121 } 122 } 123 124 // InterceptUpgraded decision to continue or drop the connection should have been made before this call 125 func (c *ConnGater) InterceptUpgraded(network.Conn) (allow bool, reason control.DisconnectReason) { 126 return true, 0 127 } 128 129 func (c *ConnGater) peerIDPassesAllFilters(p peer.ID, filters []p2p.PeerFilter) error { 130 for _, allowed := range filters { 131 if err := allowed(p); err != nil { 132 return err 133 } 134 } 135 136 return nil 137 }