github.com/geniusesgroup/libgo@v0.0.0-20220713101832-828057a9d3d4/ChaparKhane/router-connections.go (about) 1 /* For license and copyright information please see LEGAL file in repository */ 2 3 package chaparkhane 4 5 import ( 6 "hash/crc32" 7 8 "../chapar" 9 "../crypto" 10 ) 11 12 // routerConnections store pools of connection to retrieve in many ways! 13 type routerConnections struct { 14 old *routerConnection // use just in expanding 15 pathsPool [254][]*routerConnection // use 254 due to Chapar frame with TotalHop = 0||1 handled before pass it here!! 16 routersPoolLen uint32 17 routersPool []*routerConnection // It will work due to routers IDs is in increment manner! 18 } 19 20 // TODO::: convert []*routerConnection to below structure 21 type pathPool struct { 22 Len uint32 23 Add uintptr 24 } 25 26 func (rc *routerConnections) init() { 27 // TotalHop = 1 or One hop frame use just in p2p networks and not pass here!! 28 // TotalHop = 2 or Two hop implement by just one Chapar switch device! 29 rc.pathsPool[0] = make([]*routerConnection, 256) 30 // TotalHop > 2 or More than two hop implement by more than one Chapar switch device! 31 var i uint8 32 for i = 1; i < 255; i++ { 33 rc.pathsPool[i] = make([]*routerConnection, 2048) 34 } 35 36 // TODO::: use exiting router number instead of below 1024 number 37 rc.routersPool = make([]*routerConnection, 1024) 38 rc.routersPoolLen = 1024 39 } 40 41 func (rc *routerConnections) expandPathPool(hopNum uint8) (newPoolLen uint32) { 42 var poolLen uint32 = uint32(len(rc.pathsPool[hopNum])) 43 newPoolLen = poolLen * 2 44 45 var new = make([]*routerConnection, newPoolLen) 46 47 // Copy old paths 48 var exitingConn *routerConnection 49 var loc uint32 50 var i uint32 51 for i = 0; i < poolLen; i++ { 52 exitingConn = rc.pathsPool[hopNum][i] 53 if exitingConn != nil { 54 loc = crc32.ChecksumIEEE(exitingConn.Path) % newPoolLen 55 new[loc] = exitingConn 56 } 57 } 58 rc.pathsPool[hopNum] = new 59 60 return 61 } 62 63 func (rc *routerConnections) expandRoutersPool() { 64 rc.routersPool = append(rc.routersPool, make([]*routerConnection, rc.routersPoolLen)...) 65 rc.routersPoolLen *= 2 66 } 67 68 // registerNewPath use to register or overwrite a path in the related pool! 69 func (rc *routerConnections) registerNewPath(conn *routerConnection, path []byte) { 70 var pathLen uint8 = uint8(len(conn.Path)) 71 var poolLen uint32 = uint32(len(rc.pathsPool[pathLen])) 72 var loc = crc32.ChecksumIEEE(conn.Path) % poolLen 73 74 // Check collision!! 75 var exitingConn = rc.pathsPool[pathLen][loc] 76 if exitingConn != nil && exitingConn.RouterID != conn.RouterID { 77 poolLen = rc.expandPathPool(pathLen) 78 loc = crc32.ChecksumIEEE(conn.Path) % poolLen 79 } 80 81 rc.pathsPool[pathLen][loc] = conn 82 } 83 84 // registerNewRouter use to register or overwrite the given router in the related pool! 85 func (rc *routerConnections) registerNewRouter(conn *routerConnection) { 86 if conn.RouterID > rc.routersPoolLen { 87 rc.expandRoutersPool() 88 } 89 90 rc.routersPool[conn.RouterID] = conn 91 } 92 93 // MakeNewRouterConnectionReq is the request structure of MakeNewRouterConnection() 94 type MakeNewRouterConnectionReq struct { 95 RouterID uint32 96 Path []byte 97 MaxBandwidth uint64 98 Signature [256]byte 99 } 100 101 // MakeNewRouterConnection use to make connection from router advertisement! 102 func (rc *routerConnections) MakeNewRouterConnection(req *MakeNewRouterConnectionReq) { 103 // TODO::: Check signature first! 104 105 var conn *routerConnection 106 conn = rc.GetConnectionByRouterID(req.RouterID) 107 // Check if just new way to exiting router!! 108 if conn != nil && conn.RouterID == req.RouterID { 109 conn.AlternativePath = append(conn.AlternativePath, req.Path) 110 rc.registerNewPath(conn, req.Path) 111 } else { 112 conn = &routerConnection{ 113 RouterID: req.RouterID, 114 Path: req.Path, 115 ReversePath: chapar.ReversePath(req.Path), 116 Status: routerConnectionStateOpen, 117 MaxBandwidth: req.MaxBandwidth, 118 Cipher: crypto.NewGCM(crypto.NewAES256([32]byte{})), 119 } 120 rc.RegisterConnection(conn) 121 } 122 } 123 124 // RegisterConnection use to register new connection in routerConnections pools!! 125 func (rc *routerConnections) RegisterConnection(conn *routerConnection) { 126 rc.registerNewPath(conn, conn.Path) 127 rc.registerNewRouter(conn) 128 } 129 130 // GetConnectionByPath use to get a connection by path from routerConnections pool!! 131 func (rc *routerConnections) GetConnectionByPath(path []byte) (conn *routerConnection) { 132 var pathLen = len(path) 133 var poolLen uint32 = uint32(len(rc.pathsPool[pathLen])) 134 var loc = crc32.ChecksumIEEE(path) % poolLen 135 136 conn = rc.pathsPool[pathLen][loc] 137 return 138 } 139 140 // GetConnectionByRouterID use to get a connection by routerID from routerConnections pool!! 141 func (rc *routerConnections) GetConnectionByRouterID(routerID uint32) (conn *routerConnection) { 142 // respect routersPool length otherwise panic will occur! 143 if routerID <= rc.routersPoolLen { 144 conn = rc.routersPool[routerID] 145 } 146 return 147 } 148 149 // CloseConnection use to un-register exiting connection in server connection pool!! 150 func (rc *routerConnections) CloseConnection(conn *routerConnection) { 151 // TODO::: Check GC performance : delete connection vs just reset it and send it to pool of unused connection!! 152 var pathLen = len(conn.Path) 153 var poolLen uint32 = uint32(len(rc.pathsPool[pathLen])) 154 var loc = crc32.ChecksumIEEE(conn.Path) % poolLen 155 156 rc.pathsPool[pathLen][loc] = nil 157 rc.routersPool[conn.RouterID] = nil 158 }