2
0

hostmap.go 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743
  1. package nebula
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "fmt"
  6. "net"
  7. "sync"
  8. "time"
  9. "github.com/rcrowley/go-metrics"
  10. "github.com/sirupsen/logrus"
  11. "github.com/slackhq/nebula/cert"
  12. )
  13. //const ProbeLen = 100
  14. const PromoteEvery = 1000
  15. const MaxRemotes = 10
  16. // How long we should prevent roaming back to the previous IP.
  17. // This helps prevent flapping due to packets already in flight
  18. const RoamingSupressSeconds = 2
  19. type HostMap struct {
  20. sync.RWMutex //Because we concurrently read and write to our maps
  21. name string
  22. Indexes map[uint32]*HostInfo
  23. Hosts map[uint32]*HostInfo
  24. preferredRanges []*net.IPNet
  25. vpnCIDR *net.IPNet
  26. defaultRoute uint32
  27. }
  28. type HostInfo struct {
  29. remote *udpAddr
  30. Remotes []*HostInfoDest
  31. promoteCounter uint32
  32. ConnectionState *ConnectionState
  33. handshakeStart time.Time
  34. HandshakeReady bool
  35. HandshakeCounter int
  36. HandshakeComplete bool
  37. HandshakePacket map[uint8][]byte
  38. packetStore []*cachedPacket
  39. remoteIndexId uint32
  40. localIndexId uint32
  41. hostId uint32
  42. recvError int
  43. lastRoam time.Time
  44. lastRoamRemote *udpAddr
  45. }
  46. type cachedPacket struct {
  47. messageType NebulaMessageType
  48. messageSubType NebulaMessageSubType
  49. callback packetCallback
  50. packet []byte
  51. }
  52. type packetCallback func(t NebulaMessageType, st NebulaMessageSubType, h *HostInfo, p, nb, out []byte)
  53. type HostInfoDest struct {
  54. active bool
  55. addr *udpAddr
  56. //probes [ProbeLen]bool
  57. probeCounter int
  58. }
  59. type Probe struct {
  60. Addr *net.UDPAddr
  61. Counter int
  62. }
  63. func NewHostMap(name string, vpnCIDR *net.IPNet, preferredRanges []*net.IPNet) *HostMap {
  64. h := map[uint32]*HostInfo{}
  65. i := map[uint32]*HostInfo{}
  66. m := HostMap{
  67. name: name,
  68. Indexes: i,
  69. Hosts: h,
  70. preferredRanges: preferredRanges,
  71. vpnCIDR: vpnCIDR,
  72. defaultRoute: 0,
  73. }
  74. return &m
  75. }
  76. // UpdateStats takes a name and reports host and index counts to the stats collection system
  77. func (hm *HostMap) EmitStats(name string) {
  78. hm.RLock()
  79. hostLen := len(hm.Hosts)
  80. indexLen := len(hm.Indexes)
  81. hm.RUnlock()
  82. metrics.GetOrRegisterGauge("hostmap."+name+".hosts", nil).Update(int64(hostLen))
  83. metrics.GetOrRegisterGauge("hostmap."+name+".indexes", nil).Update(int64(indexLen))
  84. }
  85. func (hm *HostMap) GetIndexByVpnIP(vpnIP uint32) (uint32, error) {
  86. hm.RLock()
  87. if i, ok := hm.Hosts[vpnIP]; ok {
  88. index := i.localIndexId
  89. hm.RUnlock()
  90. return index, nil
  91. }
  92. hm.RUnlock()
  93. return 0, errors.New("vpn IP not found")
  94. }
  95. func (hm *HostMap) GetVpnIPByIndex(index uint32) (uint32, error) {
  96. hm.RLock()
  97. if i, ok := hm.Indexes[index]; ok {
  98. vpnIP := i.hostId
  99. hm.RUnlock()
  100. return vpnIP, nil
  101. }
  102. hm.RUnlock()
  103. return 0, errors.New("vpn IP not found")
  104. }
  105. func (hm *HostMap) Add(ip uint32, hostinfo *HostInfo) {
  106. hm.Lock()
  107. hm.Hosts[ip] = hostinfo
  108. hm.Unlock()
  109. }
  110. func (hm *HostMap) AddVpnIP(vpnIP uint32) *HostInfo {
  111. h := &HostInfo{}
  112. hm.RLock()
  113. if _, ok := hm.Hosts[vpnIP]; !ok {
  114. hm.RUnlock()
  115. h = &HostInfo{
  116. Remotes: []*HostInfoDest{},
  117. promoteCounter: 0,
  118. hostId: vpnIP,
  119. HandshakePacket: make(map[uint8][]byte, 0),
  120. }
  121. hm.Lock()
  122. hm.Hosts[vpnIP] = h
  123. hm.Unlock()
  124. return h
  125. } else {
  126. h = hm.Hosts[vpnIP]
  127. hm.RUnlock()
  128. return h
  129. }
  130. }
  131. func (hm *HostMap) DeleteVpnIP(vpnIP uint32) {
  132. hm.Lock()
  133. delete(hm.Hosts, vpnIP)
  134. if len(hm.Hosts) == 0 {
  135. hm.Hosts = map[uint32]*HostInfo{}
  136. }
  137. hm.Unlock()
  138. if l.Level >= logrus.DebugLevel {
  139. l.WithField("hostMap", m{"mapName": hm.name, "vpnIp": IntIp(vpnIP), "mapTotalSize": len(hm.Hosts)}).
  140. Debug("Hostmap vpnIp deleted")
  141. }
  142. }
  143. func (hm *HostMap) AddIndex(index uint32, ci *ConnectionState) (*HostInfo, error) {
  144. hm.Lock()
  145. if _, ok := hm.Indexes[index]; !ok {
  146. h := &HostInfo{
  147. ConnectionState: ci,
  148. Remotes: []*HostInfoDest{},
  149. localIndexId: index,
  150. HandshakePacket: make(map[uint8][]byte, 0),
  151. }
  152. hm.Indexes[index] = h
  153. l.WithField("hostMap", m{"mapName": hm.name, "indexNumber": index, "mapTotalSize": len(hm.Indexes),
  154. "hostinfo": m{"existing": false, "localIndexId": h.localIndexId, "hostId": IntIp(h.hostId)}}).
  155. Debug("Hostmap index added")
  156. hm.Unlock()
  157. return h, nil
  158. }
  159. hm.Unlock()
  160. return nil, fmt.Errorf("refusing to overwrite existing index: %d", index)
  161. }
  162. func (hm *HostMap) AddIndexHostInfo(index uint32, h *HostInfo) {
  163. hm.Lock()
  164. h.localIndexId = index
  165. hm.Indexes[index] = h
  166. hm.Unlock()
  167. if l.Level > logrus.DebugLevel {
  168. l.WithField("hostMap", m{"mapName": hm.name, "indexNumber": index, "mapTotalSize": len(hm.Indexes),
  169. "hostinfo": m{"existing": true, "localIndexId": h.localIndexId, "hostId": IntIp(h.hostId)}}).
  170. Debug("Hostmap index added")
  171. }
  172. }
  173. func (hm *HostMap) AddVpnIPHostInfo(vpnIP uint32, h *HostInfo) {
  174. hm.Lock()
  175. h.hostId = vpnIP
  176. hm.Hosts[vpnIP] = h
  177. hm.Unlock()
  178. if l.Level > logrus.DebugLevel {
  179. l.WithField("hostMap", m{"mapName": hm.name, "vpnIp": IntIp(vpnIP), "mapTotalSize": len(hm.Hosts),
  180. "hostinfo": m{"existing": true, "localIndexId": h.localIndexId, "hostId": IntIp(h.hostId)}}).
  181. Debug("Hostmap vpnIp added")
  182. }
  183. }
  184. func (hm *HostMap) DeleteIndex(index uint32) {
  185. hm.Lock()
  186. delete(hm.Indexes, index)
  187. if len(hm.Indexes) == 0 {
  188. hm.Indexes = map[uint32]*HostInfo{}
  189. }
  190. hm.Unlock()
  191. if l.Level >= logrus.DebugLevel {
  192. l.WithField("hostMap", m{"mapName": hm.name, "indexNumber": index, "mapTotalSize": len(hm.Indexes)}).
  193. Debug("Hostmap index deleted")
  194. }
  195. }
  196. func (hm *HostMap) QueryIndex(index uint32) (*HostInfo, error) {
  197. //TODO: we probably just want ot return bool instead of error, or at least a static error
  198. hm.RLock()
  199. if h, ok := hm.Indexes[index]; ok {
  200. hm.RUnlock()
  201. return h, nil
  202. } else {
  203. hm.RUnlock()
  204. return nil, errors.New("unable to find index")
  205. }
  206. }
  207. // This function needs to range because we don't keep a map of remote indexes.
  208. func (hm *HostMap) QueryReverseIndex(index uint32) (*HostInfo, error) {
  209. hm.RLock()
  210. for _, h := range hm.Indexes {
  211. if h.ConnectionState != nil && h.remoteIndexId == index {
  212. hm.RUnlock()
  213. return h, nil
  214. }
  215. }
  216. for _, h := range hm.Hosts {
  217. if h.ConnectionState != nil && h.remoteIndexId == index {
  218. hm.RUnlock()
  219. return h, nil
  220. }
  221. }
  222. hm.RUnlock()
  223. return nil, fmt.Errorf("unable to find reverse index or connectionstate nil in %s hostmap", hm.name)
  224. }
  225. func (hm *HostMap) AddRemote(vpnIp uint32, remote *udpAddr) *HostInfo {
  226. hm.Lock()
  227. i, v := hm.Hosts[vpnIp]
  228. if v {
  229. i.AddRemote(*remote)
  230. } else {
  231. i = &HostInfo{
  232. Remotes: []*HostInfoDest{NewHostInfoDest(remote)},
  233. promoteCounter: 0,
  234. hostId: vpnIp,
  235. HandshakePacket: make(map[uint8][]byte, 0),
  236. }
  237. i.remote = i.Remotes[0].addr
  238. hm.Hosts[vpnIp] = i
  239. l.WithField("hostMap", m{"mapName": hm.name, "vpnIp": IntIp(vpnIp), "udpAddr": remote, "mapTotalSize": len(hm.Hosts)}).
  240. Debug("Hostmap remote ip added")
  241. }
  242. i.ForcePromoteBest(hm.preferredRanges)
  243. hm.Unlock()
  244. return i
  245. }
  246. func (hm *HostMap) QueryVpnIP(vpnIp uint32) (*HostInfo, error) {
  247. return hm.queryVpnIP(vpnIp, nil)
  248. }
  249. // PromoteBestQueryVpnIP will attempt to lazily switch to the best remote every
  250. // `PromoteEvery` calls to this function for a given host.
  251. func (hm *HostMap) PromoteBestQueryVpnIP(vpnIp uint32, ifce *Interface) (*HostInfo, error) {
  252. return hm.queryVpnIP(vpnIp, ifce)
  253. }
  254. func (hm *HostMap) queryVpnIP(vpnIp uint32, promoteIfce *Interface) (*HostInfo, error) {
  255. if hm.vpnCIDR.Contains(int2ip(vpnIp)) == false && hm.defaultRoute != 0 {
  256. // FIXME: this shouldn't ship
  257. d := hm.Hosts[hm.defaultRoute]
  258. if d != nil {
  259. return hm.Hosts[hm.defaultRoute], nil
  260. }
  261. }
  262. hm.RLock()
  263. if h, ok := hm.Hosts[vpnIp]; ok {
  264. if promoteIfce != nil {
  265. h.TryPromoteBest(hm.preferredRanges, promoteIfce)
  266. }
  267. //fmt.Println(h.remote)
  268. hm.RUnlock()
  269. return h, nil
  270. } else {
  271. //return &net.UDPAddr{}, nil, errors.New("Unable to find host")
  272. hm.RUnlock()
  273. /*
  274. if lightHouse != nil {
  275. lightHouse.Query(vpnIp)
  276. return nil, errors.New("Unable to find host")
  277. }
  278. */
  279. return nil, errors.New("unable to find host")
  280. }
  281. }
  282. func (hm *HostMap) CheckHandshakeCompleteIP(vpnIP uint32) bool {
  283. hm.RLock()
  284. if i, ok := hm.Hosts[vpnIP]; ok {
  285. if i == nil {
  286. hm.RUnlock()
  287. return false
  288. }
  289. complete := i.HandshakeComplete
  290. hm.RUnlock()
  291. return complete
  292. }
  293. hm.RUnlock()
  294. return false
  295. }
  296. func (hm *HostMap) CheckHandshakeCompleteIndex(index uint32) bool {
  297. hm.RLock()
  298. if i, ok := hm.Indexes[index]; ok {
  299. if i == nil {
  300. hm.RUnlock()
  301. return false
  302. }
  303. complete := i.HandshakeComplete
  304. hm.RUnlock()
  305. return complete
  306. }
  307. hm.RUnlock()
  308. return false
  309. }
  310. func (hm *HostMap) ClearRemotes(vpnIP uint32) {
  311. hm.Lock()
  312. i := hm.Hosts[vpnIP]
  313. if i == nil {
  314. hm.Unlock()
  315. return
  316. }
  317. i.remote = nil
  318. i.Remotes = nil
  319. hm.Unlock()
  320. }
  321. func (hm *HostMap) SetDefaultRoute(ip uint32) {
  322. hm.defaultRoute = ip
  323. }
  324. func (hm *HostMap) PunchList() []*udpAddr {
  325. var list []*udpAddr
  326. hm.RLock()
  327. for _, v := range hm.Hosts {
  328. for _, r := range v.Remotes {
  329. list = append(list, r.addr)
  330. }
  331. // if h, ok := hm.Hosts[vpnIp]; ok {
  332. // hm.Hosts[vpnIp].PromoteBest(hm.preferredRanges, false)
  333. //fmt.Println(h.remote)
  334. // }
  335. }
  336. hm.RUnlock()
  337. return list
  338. }
  339. func (hm *HostMap) Punchy(conn *udpConn) {
  340. for {
  341. for _, addr := range hm.PunchList() {
  342. conn.WriteTo([]byte{1}, addr)
  343. }
  344. time.Sleep(time.Second * 30)
  345. }
  346. }
  347. func (i *HostInfo) MarshalJSON() ([]byte, error) {
  348. return json.Marshal(m{
  349. "remote": i.remote,
  350. "remotes": i.Remotes,
  351. "promote_counter": i.promoteCounter,
  352. "connection_state": i.ConnectionState,
  353. "handshake_start": i.handshakeStart,
  354. "handshake_ready": i.HandshakeReady,
  355. "handshake_counter": i.HandshakeCounter,
  356. "handshake_complete": i.HandshakeComplete,
  357. "handshake_packet": i.HandshakePacket,
  358. "packet_store": i.packetStore,
  359. "remote_index": i.remoteIndexId,
  360. "local_index": i.localIndexId,
  361. "host_id": int2ip(i.hostId),
  362. "receive_errors": i.recvError,
  363. "last_roam": i.lastRoam,
  364. "last_roam_remote": i.lastRoamRemote,
  365. })
  366. }
  367. func (i *HostInfo) BindConnectionState(cs *ConnectionState) {
  368. i.ConnectionState = cs
  369. }
  370. func (i *HostInfo) TryPromoteBest(preferredRanges []*net.IPNet, ifce *Interface) {
  371. if i.remote == nil {
  372. i.ForcePromoteBest(preferredRanges)
  373. return
  374. }
  375. i.promoteCounter++
  376. if i.promoteCounter%PromoteEvery == 0 {
  377. // return early if we are already on a preferred remote
  378. rIP := udp2ip(i.remote)
  379. for _, l := range preferredRanges {
  380. if l.Contains(rIP) {
  381. return
  382. }
  383. }
  384. // We re-query the lighthouse periodically while sending packets, so
  385. // check for new remotes in our local lighthouse cache
  386. ips := ifce.lightHouse.QueryCache(i.hostId)
  387. for _, ip := range ips {
  388. i.AddRemote(ip)
  389. }
  390. best, preferred := i.getBestRemote(preferredRanges)
  391. if preferred && !best.Equals(i.remote) {
  392. // Try to send a test packet to that host, this should
  393. // cause it to detect a roaming event and switch remotes
  394. ifce.send(test, testRequest, i.ConnectionState, i, best, []byte(""), make([]byte, 12, 12), make([]byte, mtu))
  395. }
  396. }
  397. }
  398. func (i *HostInfo) ForcePromoteBest(preferredRanges []*net.IPNet) {
  399. best, _ := i.getBestRemote(preferredRanges)
  400. if best != nil {
  401. i.remote = best
  402. }
  403. }
  404. func (i *HostInfo) getBestRemote(preferredRanges []*net.IPNet) (best *udpAddr, preferred bool) {
  405. if len(i.Remotes) > 0 {
  406. for _, r := range i.Remotes {
  407. rIP := udp2ip(r.addr)
  408. for _, l := range preferredRanges {
  409. if l.Contains(rIP) {
  410. return r.addr, true
  411. }
  412. }
  413. if best == nil || !PrivateIP(rIP) {
  414. best = r.addr
  415. }
  416. /*
  417. for _, r := range i.Remotes {
  418. // Must have > 80% probe success to be considered.
  419. //fmt.Println("GRADE:", r.addr.IP, r.Grade())
  420. if r.Grade() > float64(.8) {
  421. if localToMe.Contains(r.addr.IP) == true {
  422. best = r.addr
  423. break
  424. //i.remote = i.Remotes[c].addr
  425. } else {
  426. //}
  427. }
  428. */
  429. }
  430. return best, false
  431. }
  432. return nil, false
  433. }
  434. // rotateRemote will move remote to the next ip in the list of remote ips for this host
  435. // This is different than PromoteBest in that what is algorithmically best may not actually work.
  436. // Only known use case is when sending a stage 0 handshake.
  437. // It may be better to just send stage 0 handshakes to all known ips and sort it out in the receiver.
  438. func (i *HostInfo) rotateRemote() {
  439. // We have 0, can't rotate
  440. if len(i.Remotes) < 1 {
  441. return
  442. }
  443. if i.remote == nil {
  444. i.remote = i.Remotes[0].addr
  445. return
  446. }
  447. // We want to look at all but the very last entry since that is handled at the end
  448. for x := 0; x < len(i.Remotes)-1; x++ {
  449. // Find our current position and move to the next one in the list
  450. if i.Remotes[x].addr.Equals(i.remote) {
  451. i.remote = i.Remotes[x+1].addr
  452. return
  453. }
  454. }
  455. // Our current position was likely the last in the list, start over at 0
  456. i.remote = i.Remotes[0].addr
  457. }
  458. func (i *HostInfo) cachePacket(t NebulaMessageType, st NebulaMessageSubType, packet []byte, f packetCallback) {
  459. //TODO: return the error so we can log with more context
  460. if len(i.packetStore) < 100 {
  461. tempPacket := make([]byte, len(packet))
  462. copy(tempPacket, packet)
  463. //l.WithField("trace", string(debug.Stack())).Error("Caching packet", tempPacket)
  464. i.packetStore = append(i.packetStore, &cachedPacket{t, st, f, tempPacket})
  465. l.WithField("vpnIp", IntIp(i.hostId)).
  466. WithField("length", len(i.packetStore)).
  467. WithField("stored", true).
  468. Debugf("Packet store")
  469. } else if l.Level >= logrus.DebugLevel {
  470. l.WithField("vpnIp", IntIp(i.hostId)).
  471. WithField("length", len(i.packetStore)).
  472. WithField("stored", false).
  473. Debugf("Packet store")
  474. }
  475. }
  476. // handshakeComplete will set the connection as ready to communicate, as well as flush any stored packets
  477. func (i *HostInfo) handshakeComplete() {
  478. //TODO: I'm not certain the distinction between handshake complete and ConnectionState being ready matters because:
  479. //TODO: HandshakeComplete means send stored packets and ConnectionState.ready means we are ready to send
  480. //TODO: if the transition from HandhsakeComplete to ConnectionState.ready happens all within this function they are identical
  481. i.ConnectionState.queueLock.Lock()
  482. i.HandshakeComplete = true
  483. //TODO: this should be managed by the handshake state machine to set it based on how many handshake were seen.
  484. // Clamping it to 2 gets us out of the woods for now
  485. *i.ConnectionState.messageCounter = 2
  486. l.WithField("vpnIp", IntIp(i.hostId)).Debugf("Sending %d stored packets", len(i.packetStore))
  487. nb := make([]byte, 12, 12)
  488. out := make([]byte, mtu)
  489. for _, cp := range i.packetStore {
  490. cp.callback(cp.messageType, cp.messageSubType, i, cp.packet, nb, out)
  491. }
  492. i.packetStore = make([]*cachedPacket, 0)
  493. i.ConnectionState.ready = true
  494. i.ConnectionState.queueLock.Unlock()
  495. i.ConnectionState.certState = nil
  496. }
  497. func (i *HostInfo) RemoteUDPAddrs() []*udpAddr {
  498. var addrs []*udpAddr
  499. for _, r := range i.Remotes {
  500. addrs = append(addrs, r.addr)
  501. }
  502. return addrs
  503. }
  504. func (i *HostInfo) GetCert() *cert.NebulaCertificate {
  505. if i.ConnectionState != nil {
  506. return i.ConnectionState.peerCert
  507. }
  508. return nil
  509. }
  510. func (i *HostInfo) AddRemote(r udpAddr) *udpAddr {
  511. remote := &r
  512. //add := true
  513. for _, r := range i.Remotes {
  514. if r.addr.Equals(remote) {
  515. return r.addr
  516. //add = false
  517. }
  518. }
  519. // Trim this down if necessary
  520. if len(i.Remotes) > MaxRemotes {
  521. i.Remotes = i.Remotes[len(i.Remotes)-MaxRemotes:]
  522. }
  523. i.Remotes = append(i.Remotes, NewHostInfoDest(remote))
  524. return remote
  525. //l.Debugf("Added remote %s for vpn ip", remote)
  526. }
  527. func (i *HostInfo) SetRemote(remote udpAddr) {
  528. i.remote = i.AddRemote(remote)
  529. }
  530. func (i *HostInfo) ClearRemotes() {
  531. i.remote = nil
  532. i.Remotes = []*HostInfoDest{}
  533. }
  534. func (i *HostInfo) ClearConnectionState() {
  535. i.ConnectionState = nil
  536. }
  537. func (i *HostInfo) RecvErrorExceeded() bool {
  538. if i.recvError < 3 {
  539. i.recvError += 1
  540. return false
  541. }
  542. return true
  543. }
  544. //########################
  545. func NewHostInfoDest(addr *udpAddr) *HostInfoDest {
  546. i := &HostInfoDest{
  547. addr: addr,
  548. }
  549. return i
  550. }
  551. func (hid *HostInfoDest) MarshalJSON() ([]byte, error) {
  552. return json.Marshal(m{
  553. "active": hid.active,
  554. "address": hid.addr,
  555. "probe_count": hid.probeCounter,
  556. })
  557. }
  558. /*
  559. func (hm *HostMap) DebugRemotes(vpnIp uint32) string {
  560. s := "\n"
  561. for _, h := range hm.Hosts {
  562. for _, r := range h.Remotes {
  563. s += fmt.Sprintf("%s : %d ## %v\n", r.addr.IP.String(), r.addr.Port, r.probes)
  564. }
  565. }
  566. return s
  567. }
  568. func (d *HostInfoDest) Grade() float64 {
  569. c1 := ProbeLen
  570. for n := len(d.probes) - 1; n >= 0; n-- {
  571. if d.probes[n] == true {
  572. c1 -= 1
  573. }
  574. }
  575. return float64(c1) / float64(ProbeLen)
  576. }
  577. func (d *HostInfoDest) Grade() (float64, float64, float64) {
  578. c1 := ProbeLen
  579. c2 := ProbeLen / 2
  580. c2c := ProbeLen - ProbeLen/2
  581. c3 := ProbeLen / 5
  582. c3c := ProbeLen - ProbeLen/5
  583. for n := len(d.probes) - 1; n >= 0; n-- {
  584. if d.probes[n] == true {
  585. c1 -= 1
  586. if n >= c2c {
  587. c2 -= 1
  588. if n >= c3c {
  589. c3 -= 1
  590. }
  591. }
  592. }
  593. //if n >= d {
  594. }
  595. return float64(c3) / float64(ProbeLen/5), float64(c2) / float64(ProbeLen/2), float64(c1) / float64(ProbeLen)
  596. //return float64(c1) / float64(ProbeLen), float64(c2) / float64(ProbeLen/2), float64(c3) / float64(ProbeLen/5)
  597. }
  598. func (i *HostInfo) HandleReply(addr *net.UDPAddr, counter int) {
  599. for _, r := range i.Remotes {
  600. if r.addr.IP.Equal(addr.IP) && r.addr.Port == addr.Port {
  601. r.ProbeReceived(counter)
  602. }
  603. }
  604. }
  605. func (i *HostInfo) Probes() []*Probe {
  606. p := []*Probe{}
  607. for _, d := range i.Remotes {
  608. p = append(p, &Probe{Addr: d.addr, Counter: d.Probe()})
  609. }
  610. return p
  611. }
  612. func (d *HostInfoDest) Probe() int {
  613. //d.probes = append(d.probes, true)
  614. d.probeCounter++
  615. d.probes[d.probeCounter%ProbeLen] = true
  616. return d.probeCounter
  617. //return d.probeCounter
  618. }
  619. func (d *HostInfoDest) ProbeReceived(probeCount int) {
  620. if probeCount >= (d.probeCounter - ProbeLen) {
  621. //fmt.Println("PROBE WORKED", probeCount)
  622. //fmt.Println(d.addr, d.Grade())
  623. d.probes[probeCount%ProbeLen] = false
  624. }
  625. }
  626. */
  627. // Utility functions
  628. func localIps() *[]net.IP {
  629. //FIXME: This function is pretty garbage
  630. var ips []net.IP
  631. ifaces, _ := net.Interfaces()
  632. for _, i := range ifaces {
  633. addrs, _ := i.Addrs()
  634. for _, addr := range addrs {
  635. var ip net.IP
  636. switch v := addr.(type) {
  637. case *net.IPNet:
  638. //continue
  639. ip = v.IP
  640. case *net.IPAddr:
  641. ip = v.IP
  642. }
  643. if ip.To4() != nil && ip.IsLoopback() == false {
  644. ips = append(ips, ip)
  645. }
  646. }
  647. }
  648. return &ips
  649. }
  650. func PrivateIP(ip net.IP) bool {
  651. private := false
  652. _, private24BitBlock, _ := net.ParseCIDR("10.0.0.0/8")
  653. _, private20BitBlock, _ := net.ParseCIDR("172.16.0.0/12")
  654. _, private16BitBlock, _ := net.ParseCIDR("192.168.0.0/16")
  655. private = private24BitBlock.Contains(ip) || private20BitBlock.Contains(ip) || private16BitBlock.Contains(ip)
  656. return private
  657. }