You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

179 lines
4.7 KiB

6 years ago
6 years ago
6 years ago
  1. package p2plib
  2. import (
  3. "fmt"
  4. "net"
  5. "time"
  6. "github.com/fatih/color"
  7. )
  8. type Peer struct {
  9. ID string `json:"id"` //in the future, this will be the peer hash
  10. IP string `json:"ip"`
  11. Port string `json:"port"`
  12. RESTPort string `json:"restport"`
  13. Role string `json:"role"` //client or server
  14. Conn net.Conn `json:"conn"`
  15. }
  16. type PeersList struct {
  17. PeerID string
  18. Peers []Peer `json:"peerslist"`
  19. Date time.Time `json:"date"`
  20. }
  21. type PeersConnections struct {
  22. Incoming PeersList
  23. Outcoming PeersList
  24. Network PeersList //the peers that have been received in the lists from other peers
  25. }
  26. type ThisPeer struct {
  27. Running bool
  28. ID string
  29. RunningPeer Peer
  30. PeersConnections PeersConnections
  31. }
  32. var globalTP ThisPeer
  33. func PeerIsInPeersList(p Peer, pl []Peer) int {
  34. r := -1
  35. for i, peer := range pl {
  36. if peer.IP+":"+peer.Port == p.IP+":"+p.Port {
  37. r = i
  38. }
  39. }
  40. return r
  41. }
  42. func DeletePeerFromPeersList(p Peer, pl *PeersList) {
  43. i := PeerIsInPeersList(p, pl.Peers)
  44. if i != -1 {
  45. //delete peer from pl.Peers
  46. pl.Peers = append(pl.Peers[:i], pl.Peers[i+1:]...)
  47. }
  48. }
  49. func AppendPeerIfNoExist(pl PeersList, p Peer) PeersList {
  50. i := PeerIsInPeersList(p, pl.Peers)
  51. if i == -1 {
  52. pl.Peers = append(pl.Peers, p)
  53. }
  54. return pl
  55. }
  56. func UpdateNetworkPeersList(conn net.Conn, newPeersList PeersList) {
  57. for _, peer := range newPeersList.Peers {
  58. if GetIPPortFromConn(conn) == peer.IP+":"+peer.Port {
  59. peer.ID = newPeersList.PeerID
  60. color.Yellow(peer.ID)
  61. }
  62. i := PeerIsInPeersList(peer, globalTP.PeersConnections.Network.Peers)
  63. if i == -1 {
  64. globalTP.PeersConnections.Network.Peers = append(globalTP.PeersConnections.Network.Peers, peer)
  65. } else {
  66. fmt.Println(globalTP.PeersConnections.Network.Peers[i])
  67. globalTP.PeersConnections.Network.Peers[i].ID = peer.ID
  68. }
  69. }
  70. }
  71. func SearchPeerAndUpdate(p Peer) {
  72. for _, peer := range globalTP.PeersConnections.Outcoming.Peers {
  73. color.Red(p.IP + ":" + p.Port)
  74. color.Yellow(peer.IP + ":" + peer.Port)
  75. if p.IP+":"+p.Port == peer.IP+":"+peer.Port {
  76. peer.ID = p.ID
  77. }
  78. }
  79. }
  80. //send the outcomingPeersList to all the peers except the peer p that has send the outcomingPeersList
  81. func PropagatePeersList(p Peer) {
  82. for _, peer := range globalTP.PeersConnections.Network.Peers {
  83. if peer.Conn != nil {
  84. if peer.ID != p.ID && p.ID != "" {
  85. color.Yellow(peer.ID + " - " + p.ID)
  86. var msg Msg
  87. msg.Construct("PeersList", "here my outcomingPeersList")
  88. msg.PeersList = globalTP.PeersConnections.Outcoming
  89. msgB := msg.ToBytes()
  90. _, err := peer.Conn.Write(msgB)
  91. check(err)
  92. } else {
  93. /*
  94. for the moment, this is not being called, due that in the IncomingPeersList,
  95. there is no peer.ID, so in the comparation wih the peer that has send the
  96. peersList, is comparing ID with "", so nevere enters this 'else' section
  97. maybe it's not needed. TODO check if it's needed the PeerList_Response
  98. For the moment is working without it
  99. */
  100. //to the peer that has sent the peerList, we send our PeersList
  101. var msg Msg
  102. msg.Construct("PeersList_Response", "here my outcomingPeersList")
  103. msg.PeersList = globalTP.PeersConnections.Outcoming
  104. msgB := msg.ToBytes()
  105. _, err := peer.Conn.Write(msgB)
  106. check(err)
  107. }
  108. } else {
  109. //connect to peer
  110. if peer.ID != p.ID && peer.ID != globalTP.RunningPeer.ID {
  111. if PeerIsInPeersList(peer, globalTP.PeersConnections.Outcoming.Peers) == -1 {
  112. color.Red("no connection, connecting to peer: " + peer.Port)
  113. ConnectToPeer(peer)
  114. }
  115. }
  116. }
  117. }
  118. }
  119. func PrintPeersList() {
  120. fmt.Println("")
  121. color.Blue("runningPeer.ID: " + globalTP.RunningPeer.ID)
  122. color.Green("OUTCOMING PEERSLIST:")
  123. for _, peer := range globalTP.PeersConnections.Outcoming.Peers {
  124. fmt.Println(peer)
  125. }
  126. color.Green("INCOMING PEERSLIST:")
  127. for _, peer := range globalTP.PeersConnections.Incoming.Peers {
  128. fmt.Println(peer)
  129. }
  130. color.Green("NETWORK PEERSLIST:")
  131. for _, peer := range globalTP.PeersConnections.Network.Peers {
  132. fmt.Println(peer)
  133. }
  134. fmt.Println("")
  135. }
  136. func PropagateData(p Peer, s string) {
  137. //prepare the msg to send to all connected peers
  138. var msg Msg
  139. msg.Construct("Data", "new Data")
  140. msg.Data = []byte(s)
  141. msgB := msg.ToBytes()
  142. for _, peer := range globalTP.PeersConnections.Outcoming.Peers {
  143. if peer.Conn != nil {
  144. if peer.ID != p.ID && p.ID != "" {
  145. _, err := peer.Conn.Write(msgB)
  146. check(err)
  147. }
  148. }
  149. }
  150. }
  151. //send the block to all the peers of the outcomingPeersList
  152. /*func PropagateBlock(b Block) {
  153. //prepare the msg to send to all connected peers
  154. var msg Msg
  155. msg.construct("Block", "new block")
  156. msg.Block = b
  157. msgB := msg.toBytes()
  158. for _, peer := range outcomingPeersList.Peers {
  159. if peer.Conn != nil {
  160. _, err := peer.Conn.Write(msgB)
  161. check(err)
  162. }
  163. }
  164. }*/