| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869 |
- package kcp
- import (
- "sync"
- "time"
- )
- var (
- // BlacklistDuration sets a duration for which a session is blacklisted
- // once it's established. This is simillar to TIME_WAIT state in TCP, whereby
- // any connection attempt with the same session parameters is ignored for
- // some amount of time.
- //
- // This is only useful when dial attempts happen from a pre-determined port,
- // for example when you are dialing from the same connection you are listening on
- // to punch through NAT, and helps with the fact that KCP is state-less.
- // This helps better deal with scenarios where a process on one of the side (A)
- // get's restarted, and stray packets from other side (B) makes it look like
- // as if someone is trying to connect to A. Even if session dies on B,
- // new stray reply packets from A resurrect the session on B, causing the
- // session to be alive forever.
- BlacklistDuration time.Duration
- blacklist = blacklistMap{
- entries: make(map[sessionKey]time.Time),
- }
- )
- // a global map for blacklisting conversations
- type blacklistMap struct {
- entries map[sessionKey]time.Time
- reapAt time.Time
- mut sync.Mutex
- }
- func (m *blacklistMap) add(address string, conv uint32) {
- if BlacklistDuration == 0 {
- return
- }
- m.mut.Lock()
- timeout := time.Now().Add(BlacklistDuration)
- m.entries[sessionKey{
- addr: address,
- convID: conv,
- }] = timeout
- m.reap()
- m.mut.Unlock()
- }
- func (m *blacklistMap) has(address string, conv uint32) bool {
- if BlacklistDuration == 0 {
- return false
- }
- m.mut.Lock()
- t, ok := m.entries[sessionKey{
- addr: address,
- convID: conv,
- }]
- m.mut.Unlock()
- return ok && t.After(time.Now())
- }
- func (m *blacklistMap) reap() {
- now := time.Now()
- for k, t := range m.entries {
- if t.Before(now) {
- delete(m.entries, k)
- }
- }
- }
|