server: adds hybrid black/whitelist filtering to user agents

This commit is contained in:
Conner Fromknecht 2018-01-09 19:12:46 -08:00 committed by Conner Fromknecht
parent 9bfb2ca034
commit d3ecdc91a9
No known key found for this signature in database
GPG key ID: E7D737B67FA592C7

View file

@ -246,6 +246,14 @@ type server struct {
// messages for each filter type.
cfCheckptCaches map[wire.FilterType][]cfHeaderKV
cfCheckptCachesMtx sync.RWMutex
// agentBlacklist is a list of blacklisted substrings by which to filter
// user agents.
agentBlacklist []string
// agentWhitelist is a list of whitelisted user agent substrings, no
// whitelisting will be applied if the list is empty or nil.
agentWhitelist []string
}
// serverPeer extends the peer to maintain state shared by the server and
@ -1586,6 +1594,12 @@ func (s *server) handleAddPeerMsg(state *peerState, sp *serverPeer) bool {
return false
}
// Disconnect peers with unwanted user agents.
if sp.HasUndesiredUserAgent(s.agentBlacklist, s.agentWhitelist) {
sp.Disconnect()
return false
}
// Ignore new peers if we're shutting down.
if atomic.LoadInt32(&s.shutdown) != 0 {
srvrLog.Infof("New peer %s ignored - server is shutting down", sp)
@ -3133,3 +3147,47 @@ func mergeCheckpoints(defaultCheckpoints, additional []chaincfg.Checkpoint) []ch
sort.Sort(checkpointSorter(checkpoints))
return checkpoints
}
// HasUndesiredUserAgent determines whether the server should continue to pursue
// a connection with this peer based on its advertised user agent. It performs
// the following steps:
// 1) Reject the peer if it contains a blacklisted agent.
// 2) If no whitelist is provided, accept all user agents.
// 3) Accept the peer if it contains a whitelisted agent.
// 4) Reject all other peers.
func (sp *serverPeer) HasUndesiredUserAgent(blacklistedAgents,
whitelistedAgents []string) bool {
agent := sp.UserAgent()
// First, if peer's user agent contains any blacklisted substring, we
// will ignore the connection request.
for _, blacklistedAgent := range blacklistedAgents {
if strings.Contains(agent, blacklistedAgent) {
srvrLog.Debugf("Ignoring peer %s, user agent "+
"contains blacklisted user agent: %s", sp,
agent)
return true
}
}
// If no whitelist is provided, we will accept all user agents.
if len(whitelistedAgents) == 0 {
return false
}
// Peer's user agent passed blacklist. Now check to see if it contains
// one of our whitelisted user agents, if so accept.
for _, whitelistedAgent := range whitelistedAgents {
if strings.Contains(agent, whitelistedAgent) {
return false
}
}
// Otherwise, the peer's user agent was not included in our whitelist.
// Ignore just in case it could stall the initial block download.
srvrLog.Debugf("Ignoring peer %s, user agent: %s not found in "+
"whitelist", sp, agent)
return true
}