123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799 |
- package nebula
- import (
- "encoding/json"
- "errors"
- "fmt"
- "net"
- "sync"
- "time"
- "github.com/rcrowley/go-metrics"
- "github.com/sirupsen/logrus"
- "github.com/slackhq/nebula/cert"
- )
- //const ProbeLen = 100
- const PromoteEvery = 1000
- const MaxRemotes = 10
- // How long we should prevent roaming back to the previous IP.
- // This helps prevent flapping due to packets already in flight
- const RoamingSupressSeconds = 2
- type HostMap struct {
- sync.RWMutex //Because we concurrently read and write to our maps
- name string
- Indexes map[uint32]*HostInfo
- Hosts map[uint32]*HostInfo
- preferredRanges []*net.IPNet
- vpnCIDR *net.IPNet
- defaultRoute uint32
- unsafeRoutes *CIDRTree
- }
- type HostInfo struct {
- remote *udpAddr
- Remotes []*HostInfoDest
- promoteCounter uint32
- ConnectionState *ConnectionState
- handshakeStart time.Time
- HandshakeReady bool
- HandshakeCounter int
- HandshakeComplete bool
- HandshakePacket map[uint8][]byte
- packetStore []*cachedPacket
- remoteIndexId uint32
- localIndexId uint32
- hostId uint32
- recvError int
- remoteCidr *CIDRTree
- lastRoam time.Time
- lastRoamRemote *udpAddr
- }
- type cachedPacket struct {
- messageType NebulaMessageType
- messageSubType NebulaMessageSubType
- callback packetCallback
- packet []byte
- }
- type packetCallback func(t NebulaMessageType, st NebulaMessageSubType, h *HostInfo, p, nb, out []byte)
- type HostInfoDest struct {
- active bool
- addr *udpAddr
- //probes [ProbeLen]bool
- probeCounter int
- }
- type Probe struct {
- Addr *net.UDPAddr
- Counter int
- }
- func NewHostMap(name string, vpnCIDR *net.IPNet, preferredRanges []*net.IPNet) *HostMap {
- h := map[uint32]*HostInfo{}
- i := map[uint32]*HostInfo{}
- m := HostMap{
- name: name,
- Indexes: i,
- Hosts: h,
- preferredRanges: preferredRanges,
- vpnCIDR: vpnCIDR,
- defaultRoute: 0,
- unsafeRoutes: NewCIDRTree(),
- }
- return &m
- }
- // UpdateStats takes a name and reports host and index counts to the stats collection system
- func (hm *HostMap) EmitStats(name string) {
- hm.RLock()
- hostLen := len(hm.Hosts)
- indexLen := len(hm.Indexes)
- hm.RUnlock()
- metrics.GetOrRegisterGauge("hostmap."+name+".hosts", nil).Update(int64(hostLen))
- metrics.GetOrRegisterGauge("hostmap."+name+".indexes", nil).Update(int64(indexLen))
- }
- func (hm *HostMap) GetIndexByVpnIP(vpnIP uint32) (uint32, error) {
- hm.RLock()
- if i, ok := hm.Hosts[vpnIP]; ok {
- index := i.localIndexId
- hm.RUnlock()
- return index, nil
- }
- hm.RUnlock()
- return 0, errors.New("vpn IP not found")
- }
- func (hm *HostMap) GetVpnIPByIndex(index uint32) (uint32, error) {
- hm.RLock()
- if i, ok := hm.Indexes[index]; ok {
- vpnIP := i.hostId
- hm.RUnlock()
- return vpnIP, nil
- }
- hm.RUnlock()
- return 0, errors.New("vpn IP not found")
- }
- func (hm *HostMap) Add(ip uint32, hostinfo *HostInfo) {
- hm.Lock()
- hm.Hosts[ip] = hostinfo
- hm.Unlock()
- }
- func (hm *HostMap) AddVpnIP(vpnIP uint32) *HostInfo {
- h := &HostInfo{}
- hm.RLock()
- if _, ok := hm.Hosts[vpnIP]; !ok {
- hm.RUnlock()
- h = &HostInfo{
- Remotes: []*HostInfoDest{},
- promoteCounter: 0,
- hostId: vpnIP,
- HandshakePacket: make(map[uint8][]byte, 0),
- }
- hm.Lock()
- hm.Hosts[vpnIP] = h
- hm.Unlock()
- return h
- } else {
- h = hm.Hosts[vpnIP]
- hm.RUnlock()
- return h
- }
- }
- func (hm *HostMap) DeleteVpnIP(vpnIP uint32) {
- hm.Lock()
- delete(hm.Hosts, vpnIP)
- if len(hm.Hosts) == 0 {
- hm.Hosts = map[uint32]*HostInfo{}
- }
- hm.Unlock()
- if l.Level >= logrus.DebugLevel {
- l.WithField("hostMap", m{"mapName": hm.name, "vpnIp": IntIp(vpnIP), "mapTotalSize": len(hm.Hosts)}).
- Debug("Hostmap vpnIp deleted")
- }
- }
- func (hm *HostMap) AddIndex(index uint32, ci *ConnectionState) (*HostInfo, error) {
- hm.Lock()
- if _, ok := hm.Indexes[index]; !ok {
- h := &HostInfo{
- ConnectionState: ci,
- Remotes: []*HostInfoDest{},
- localIndexId: index,
- HandshakePacket: make(map[uint8][]byte, 0),
- }
- hm.Indexes[index] = h
- l.WithField("hostMap", m{"mapName": hm.name, "indexNumber": index, "mapTotalSize": len(hm.Indexes),
- "hostinfo": m{"existing": false, "localIndexId": h.localIndexId, "hostId": IntIp(h.hostId)}}).
- Debug("Hostmap index added")
- hm.Unlock()
- return h, nil
- }
- hm.Unlock()
- return nil, fmt.Errorf("refusing to overwrite existing index: %d", index)
- }
- func (hm *HostMap) AddIndexHostInfo(index uint32, h *HostInfo) {
- hm.Lock()
- h.localIndexId = index
- hm.Indexes[index] = h
- hm.Unlock()
- if l.Level > logrus.DebugLevel {
- l.WithField("hostMap", m{"mapName": hm.name, "indexNumber": index, "mapTotalSize": len(hm.Indexes),
- "hostinfo": m{"existing": true, "localIndexId": h.localIndexId, "hostId": IntIp(h.hostId)}}).
- Debug("Hostmap index added")
- }
- }
- func (hm *HostMap) AddVpnIPHostInfo(vpnIP uint32, h *HostInfo) {
- hm.Lock()
- h.hostId = vpnIP
- hm.Hosts[vpnIP] = h
- hm.Unlock()
- if l.Level > logrus.DebugLevel {
- l.WithField("hostMap", m{"mapName": hm.name, "vpnIp": IntIp(vpnIP), "mapTotalSize": len(hm.Hosts),
- "hostinfo": m{"existing": true, "localIndexId": h.localIndexId, "hostId": IntIp(h.hostId)}}).
- Debug("Hostmap vpnIp added")
- }
- }
- func (hm *HostMap) DeleteIndex(index uint32) {
- hm.Lock()
- delete(hm.Indexes, index)
- if len(hm.Indexes) == 0 {
- hm.Indexes = map[uint32]*HostInfo{}
- }
- hm.Unlock()
- if l.Level >= logrus.DebugLevel {
- l.WithField("hostMap", m{"mapName": hm.name, "indexNumber": index, "mapTotalSize": len(hm.Indexes)}).
- Debug("Hostmap index deleted")
- }
- }
- func (hm *HostMap) QueryIndex(index uint32) (*HostInfo, error) {
- //TODO: we probably just want ot return bool instead of error, or at least a static error
- hm.RLock()
- if h, ok := hm.Indexes[index]; ok {
- hm.RUnlock()
- return h, nil
- } else {
- hm.RUnlock()
- return nil, errors.New("unable to find index")
- }
- }
- // This function needs to range because we don't keep a map of remote indexes.
- func (hm *HostMap) QueryReverseIndex(index uint32) (*HostInfo, error) {
- hm.RLock()
- for _, h := range hm.Indexes {
- if h.ConnectionState != nil && h.remoteIndexId == index {
- hm.RUnlock()
- return h, nil
- }
- }
- for _, h := range hm.Hosts {
- if h.ConnectionState != nil && h.remoteIndexId == index {
- hm.RUnlock()
- return h, nil
- }
- }
- hm.RUnlock()
- return nil, fmt.Errorf("unable to find reverse index or connectionstate nil in %s hostmap", hm.name)
- }
- func (hm *HostMap) AddRemote(vpnIp uint32, remote *udpAddr) *HostInfo {
- hm.Lock()
- i, v := hm.Hosts[vpnIp]
- if v {
- i.AddRemote(*remote)
- } else {
- i = &HostInfo{
- Remotes: []*HostInfoDest{NewHostInfoDest(remote)},
- promoteCounter: 0,
- hostId: vpnIp,
- HandshakePacket: make(map[uint8][]byte, 0),
- }
- i.remote = i.Remotes[0].addr
- hm.Hosts[vpnIp] = i
- l.WithField("hostMap", m{"mapName": hm.name, "vpnIp": IntIp(vpnIp), "udpAddr": remote, "mapTotalSize": len(hm.Hosts)}).
- Debug("Hostmap remote ip added")
- }
- i.ForcePromoteBest(hm.preferredRanges)
- hm.Unlock()
- return i
- }
- func (hm *HostMap) QueryVpnIP(vpnIp uint32) (*HostInfo, error) {
- return hm.queryVpnIP(vpnIp, nil)
- }
- // PromoteBestQueryVpnIP will attempt to lazily switch to the best remote every
- // `PromoteEvery` calls to this function for a given host.
- func (hm *HostMap) PromoteBestQueryVpnIP(vpnIp uint32, ifce *Interface) (*HostInfo, error) {
- return hm.queryVpnIP(vpnIp, ifce)
- }
- func (hm *HostMap) queryVpnIP(vpnIp uint32, promoteIfce *Interface) (*HostInfo, error) {
- hm.RLock()
- if h, ok := hm.Hosts[vpnIp]; ok {
- if promoteIfce != nil {
- h.TryPromoteBest(hm.preferredRanges, promoteIfce)
- }
- //fmt.Println(h.remote)
- hm.RUnlock()
- return h, nil
- } else {
- //return &net.UDPAddr{}, nil, errors.New("Unable to find host")
- hm.RUnlock()
- /*
- if lightHouse != nil {
- lightHouse.Query(vpnIp)
- return nil, errors.New("Unable to find host")
- }
- */
- return nil, errors.New("unable to find host")
- }
- }
- func (hm *HostMap) queryUnsafeRoute(ip uint32) uint32 {
- r := hm.unsafeRoutes.MostSpecificContains(ip)
- if r != nil {
- return r.(uint32)
- } else {
- return 0
- }
- }
- func (hm *HostMap) CheckHandshakeCompleteIP(vpnIP uint32) bool {
- hm.RLock()
- if i, ok := hm.Hosts[vpnIP]; ok {
- if i == nil {
- hm.RUnlock()
- return false
- }
- complete := i.HandshakeComplete
- hm.RUnlock()
- return complete
- }
- hm.RUnlock()
- return false
- }
- func (hm *HostMap) CheckHandshakeCompleteIndex(index uint32) bool {
- hm.RLock()
- if i, ok := hm.Indexes[index]; ok {
- if i == nil {
- hm.RUnlock()
- return false
- }
- complete := i.HandshakeComplete
- hm.RUnlock()
- return complete
- }
- hm.RUnlock()
- return false
- }
- func (hm *HostMap) ClearRemotes(vpnIP uint32) {
- hm.Lock()
- i := hm.Hosts[vpnIP]
- if i == nil {
- hm.Unlock()
- return
- }
- i.remote = nil
- i.Remotes = nil
- hm.Unlock()
- }
- func (hm *HostMap) SetDefaultRoute(ip uint32) {
- hm.defaultRoute = ip
- }
- func (hm *HostMap) PunchList() []*udpAddr {
- var list []*udpAddr
- hm.RLock()
- for _, v := range hm.Hosts {
- for _, r := range v.Remotes {
- list = append(list, r.addr)
- }
- // if h, ok := hm.Hosts[vpnIp]; ok {
- // hm.Hosts[vpnIp].PromoteBest(hm.preferredRanges, false)
- //fmt.Println(h.remote)
- // }
- }
- hm.RUnlock()
- return list
- }
- func (hm *HostMap) Punchy(conn *udpConn) {
- for {
- for _, addr := range hm.PunchList() {
- conn.WriteTo([]byte{1}, addr)
- }
- time.Sleep(time.Second * 30)
- }
- }
- func (hm *HostMap) addUnsafeRoutes(routes *[]route) {
- for _, r := range *routes {
- l.WithField("route", r.route).WithField("via", r.via).Warn("Adding UNSAFE Route")
- hm.unsafeRoutes.AddCIDR(r.route, ip2int(*r.via))
- }
- }
- func (i *HostInfo) MarshalJSON() ([]byte, error) {
- return json.Marshal(m{
- "remote": i.remote,
- "remotes": i.Remotes,
- "promote_counter": i.promoteCounter,
- "connection_state": i.ConnectionState,
- "handshake_start": i.handshakeStart,
- "handshake_ready": i.HandshakeReady,
- "handshake_counter": i.HandshakeCounter,
- "handshake_complete": i.HandshakeComplete,
- "handshake_packet": i.HandshakePacket,
- "packet_store": i.packetStore,
- "remote_index": i.remoteIndexId,
- "local_index": i.localIndexId,
- "host_id": int2ip(i.hostId),
- "receive_errors": i.recvError,
- "last_roam": i.lastRoam,
- "last_roam_remote": i.lastRoamRemote,
- })
- }
- func (i *HostInfo) BindConnectionState(cs *ConnectionState) {
- i.ConnectionState = cs
- }
- func (i *HostInfo) TryPromoteBest(preferredRanges []*net.IPNet, ifce *Interface) {
- if i.remote == nil {
- i.ForcePromoteBest(preferredRanges)
- return
- }
- i.promoteCounter++
- if i.promoteCounter%PromoteEvery == 0 {
- // return early if we are already on a preferred remote
- rIP := udp2ip(i.remote)
- for _, l := range preferredRanges {
- if l.Contains(rIP) {
- return
- }
- }
- // We re-query the lighthouse periodically while sending packets, so
- // check for new remotes in our local lighthouse cache
- ips := ifce.lightHouse.QueryCache(i.hostId)
- for _, ip := range ips {
- i.AddRemote(ip)
- }
- best, preferred := i.getBestRemote(preferredRanges)
- if preferred && !best.Equals(i.remote) {
- // Try to send a test packet to that host, this should
- // cause it to detect a roaming event and switch remotes
- ifce.send(test, testRequest, i.ConnectionState, i, best, []byte(""), make([]byte, 12, 12), make([]byte, mtu))
- }
- }
- }
- func (i *HostInfo) ForcePromoteBest(preferredRanges []*net.IPNet) {
- best, _ := i.getBestRemote(preferredRanges)
- if best != nil {
- i.remote = best
- }
- }
- func (i *HostInfo) getBestRemote(preferredRanges []*net.IPNet) (best *udpAddr, preferred bool) {
- if len(i.Remotes) > 0 {
- for _, r := range i.Remotes {
- rIP := udp2ip(r.addr)
- for _, l := range preferredRanges {
- if l.Contains(rIP) {
- return r.addr, true
- }
- }
- if best == nil || !PrivateIP(rIP) {
- best = r.addr
- }
- /*
- for _, r := range i.Remotes {
- // Must have > 80% probe success to be considered.
- //fmt.Println("GRADE:", r.addr.IP, r.Grade())
- if r.Grade() > float64(.8) {
- if localToMe.Contains(r.addr.IP) == true {
- best = r.addr
- break
- //i.remote = i.Remotes[c].addr
- } else {
- //}
- }
- */
- }
- return best, false
- }
- return nil, false
- }
- // rotateRemote will move remote to the next ip in the list of remote ips for this host
- // This is different than PromoteBest in that what is algorithmically best may not actually work.
- // Only known use case is when sending a stage 0 handshake.
- // It may be better to just send stage 0 handshakes to all known ips and sort it out in the receiver.
- func (i *HostInfo) rotateRemote() {
- // We have 0, can't rotate
- if len(i.Remotes) < 1 {
- return
- }
- if i.remote == nil {
- i.remote = i.Remotes[0].addr
- return
- }
- // We want to look at all but the very last entry since that is handled at the end
- for x := 0; x < len(i.Remotes)-1; x++ {
- // Find our current position and move to the next one in the list
- if i.Remotes[x].addr.Equals(i.remote) {
- i.remote = i.Remotes[x+1].addr
- return
- }
- }
- // Our current position was likely the last in the list, start over at 0
- i.remote = i.Remotes[0].addr
- }
- func (i *HostInfo) cachePacket(t NebulaMessageType, st NebulaMessageSubType, packet []byte, f packetCallback) {
- //TODO: return the error so we can log with more context
- if len(i.packetStore) < 100 {
- tempPacket := make([]byte, len(packet))
- copy(tempPacket, packet)
- //l.WithField("trace", string(debug.Stack())).Error("Caching packet", tempPacket)
- i.packetStore = append(i.packetStore, &cachedPacket{t, st, f, tempPacket})
- i.logger().
- WithField("length", len(i.packetStore)).
- WithField("stored", true).
- Debugf("Packet store")
- } else if l.Level >= logrus.DebugLevel {
- i.logger().
- WithField("length", len(i.packetStore)).
- WithField("stored", false).
- Debugf("Packet store")
- }
- }
- // handshakeComplete will set the connection as ready to communicate, as well as flush any stored packets
- func (i *HostInfo) handshakeComplete() {
- //TODO: I'm not certain the distinction between handshake complete and ConnectionState being ready matters because:
- //TODO: HandshakeComplete means send stored packets and ConnectionState.ready means we are ready to send
- //TODO: if the transition from HandhsakeComplete to ConnectionState.ready happens all within this function they are identical
- i.ConnectionState.queueLock.Lock()
- i.HandshakeComplete = true
- //TODO: this should be managed by the handshake state machine to set it based on how many handshake were seen.
- // Clamping it to 2 gets us out of the woods for now
- *i.ConnectionState.messageCounter = 2
- i.logger().Debugf("Sending %d stored packets", len(i.packetStore))
- nb := make([]byte, 12, 12)
- out := make([]byte, mtu)
- for _, cp := range i.packetStore {
- cp.callback(cp.messageType, cp.messageSubType, i, cp.packet, nb, out)
- }
- i.packetStore = make([]*cachedPacket, 0)
- i.ConnectionState.ready = true
- i.ConnectionState.queueLock.Unlock()
- i.ConnectionState.certState = nil
- }
- func (i *HostInfo) RemoteUDPAddrs() []*udpAddr {
- var addrs []*udpAddr
- for _, r := range i.Remotes {
- addrs = append(addrs, r.addr)
- }
- return addrs
- }
- func (i *HostInfo) GetCert() *cert.NebulaCertificate {
- if i.ConnectionState != nil {
- return i.ConnectionState.peerCert
- }
- return nil
- }
- func (i *HostInfo) AddRemote(r udpAddr) *udpAddr {
- remote := &r
- //add := true
- for _, r := range i.Remotes {
- if r.addr.Equals(remote) {
- return r.addr
- //add = false
- }
- }
- // Trim this down if necessary
- if len(i.Remotes) > MaxRemotes {
- i.Remotes = i.Remotes[len(i.Remotes)-MaxRemotes:]
- }
- i.Remotes = append(i.Remotes, NewHostInfoDest(remote))
- return remote
- //l.Debugf("Added remote %s for vpn ip", remote)
- }
- func (i *HostInfo) SetRemote(remote udpAddr) {
- i.remote = i.AddRemote(remote)
- }
- func (i *HostInfo) ClearRemotes() {
- i.remote = nil
- i.Remotes = []*HostInfoDest{}
- }
- func (i *HostInfo) ClearConnectionState() {
- i.ConnectionState = nil
- }
- func (i *HostInfo) RecvErrorExceeded() bool {
- if i.recvError < 3 {
- i.recvError += 1
- return false
- }
- return true
- }
- func (i *HostInfo) CreateRemoteCIDR(c *cert.NebulaCertificate) {
- if len(c.Details.Ips) == 1 && len(c.Details.Subnets) == 0 {
- // Simple case, no CIDRTree needed
- return
- }
- remoteCidr := NewCIDRTree()
- for _, ip := range c.Details.Ips {
- remoteCidr.AddCIDR(&net.IPNet{IP: ip.IP, Mask: net.IPMask{255, 255, 255, 255}}, struct{}{})
- }
- for _, n := range c.Details.Subnets {
- remoteCidr.AddCIDR(n, struct{}{})
- }
- i.remoteCidr = remoteCidr
- }
- func (i *HostInfo) logger() *logrus.Entry {
- if i == nil {
- return logrus.NewEntry(l)
- }
- li := l.WithField("vpnIp", IntIp(i.hostId))
- if connState := i.ConnectionState; connState != nil {
- if peerCert := connState.peerCert; peerCert != nil {
- li = li.WithField("certName", peerCert.Details.Name)
- }
- }
- return li
- }
- //########################
- func NewHostInfoDest(addr *udpAddr) *HostInfoDest {
- i := &HostInfoDest{
- addr: addr,
- }
- return i
- }
- func (hid *HostInfoDest) MarshalJSON() ([]byte, error) {
- return json.Marshal(m{
- "active": hid.active,
- "address": hid.addr,
- "probe_count": hid.probeCounter,
- })
- }
- /*
- func (hm *HostMap) DebugRemotes(vpnIp uint32) string {
- s := "\n"
- for _, h := range hm.Hosts {
- for _, r := range h.Remotes {
- s += fmt.Sprintf("%s : %d ## %v\n", r.addr.IP.String(), r.addr.Port, r.probes)
- }
- }
- return s
- }
- func (d *HostInfoDest) Grade() float64 {
- c1 := ProbeLen
- for n := len(d.probes) - 1; n >= 0; n-- {
- if d.probes[n] == true {
- c1 -= 1
- }
- }
- return float64(c1) / float64(ProbeLen)
- }
- func (d *HostInfoDest) Grade() (float64, float64, float64) {
- c1 := ProbeLen
- c2 := ProbeLen / 2
- c2c := ProbeLen - ProbeLen/2
- c3 := ProbeLen / 5
- c3c := ProbeLen - ProbeLen/5
- for n := len(d.probes) - 1; n >= 0; n-- {
- if d.probes[n] == true {
- c1 -= 1
- if n >= c2c {
- c2 -= 1
- if n >= c3c {
- c3 -= 1
- }
- }
- }
- //if n >= d {
- }
- return float64(c3) / float64(ProbeLen/5), float64(c2) / float64(ProbeLen/2), float64(c1) / float64(ProbeLen)
- //return float64(c1) / float64(ProbeLen), float64(c2) / float64(ProbeLen/2), float64(c3) / float64(ProbeLen/5)
- }
- func (i *HostInfo) HandleReply(addr *net.UDPAddr, counter int) {
- for _, r := range i.Remotes {
- if r.addr.IP.Equal(addr.IP) && r.addr.Port == addr.Port {
- r.ProbeReceived(counter)
- }
- }
- }
- func (i *HostInfo) Probes() []*Probe {
- p := []*Probe{}
- for _, d := range i.Remotes {
- p = append(p, &Probe{Addr: d.addr, Counter: d.Probe()})
- }
- return p
- }
- func (d *HostInfoDest) Probe() int {
- //d.probes = append(d.probes, true)
- d.probeCounter++
- d.probes[d.probeCounter%ProbeLen] = true
- return d.probeCounter
- //return d.probeCounter
- }
- func (d *HostInfoDest) ProbeReceived(probeCount int) {
- if probeCount >= (d.probeCounter - ProbeLen) {
- //fmt.Println("PROBE WORKED", probeCount)
- //fmt.Println(d.addr, d.Grade())
- d.probes[probeCount%ProbeLen] = false
- }
- }
- */
- // Utility functions
- func localIps(allowList *AllowList) *[]net.IP {
- //FIXME: This function is pretty garbage
- var ips []net.IP
- ifaces, _ := net.Interfaces()
- for _, i := range ifaces {
- allow := allowList.AllowName(i.Name)
- l.WithField("interfaceName", i.Name).WithField("allow", allow).Debug("localAllowList.AllowName")
- if !allow {
- continue
- }
- addrs, _ := i.Addrs()
- for _, addr := range addrs {
- var ip net.IP
- switch v := addr.(type) {
- case *net.IPNet:
- //continue
- ip = v.IP
- case *net.IPAddr:
- ip = v.IP
- }
- if ip.To4() != nil && ip.IsLoopback() == false {
- allow := allowList.Allow(ip2int(ip))
- l.WithField("localIp", ip).WithField("allow", allow).Debug("localAllowList.Allow")
- if !allow {
- continue
- }
- ips = append(ips, ip)
- }
- }
- }
- return &ips
- }
- func PrivateIP(ip net.IP) bool {
- private := false
- _, private24BitBlock, _ := net.ParseCIDR("10.0.0.0/8")
- _, private20BitBlock, _ := net.ParseCIDR("172.16.0.0/12")
- _, private16BitBlock, _ := net.ParseCIDR("192.168.0.0/16")
- private = private24BitBlock.Contains(ip) || private20BitBlock.Contains(ip) || private16BitBlock.Contains(ip)
- return private
- }
|