github.com/geniusesgroup/libgo@v0.0.0-20220713101832-828057a9d3d4/ChaparKhane/xp-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  // xpConnections store pools of connection to retrieve in many ways!
    13  type xpConnections struct {
    14  	old        *xpConnections // use just in expanding
    15  	pathsPool  [254][]*routerConnection
    16  	XPsPoolLen uint32
    17  	XPsPool    []*xpPool
    18  }
    19  
    20  type xpPool struct {
    21  	XPID     uint32
    22  	FreeID   uint8
    23  	RouterID [8]uint32
    24  	Conn     [8]*routerConnection
    25  }
    26  
    27  func (xp *xpConnections) init() {
    28  	// TotalHop = 1 or One hop frame use just in p2p networks and not pass here!!
    29  	// TotalHop = 2 or Two hop implement by just one Chapar switch device!
    30  	xp.pathsPool[0] = make([]*routerConnection, 256)
    31  	// TotalHop > 2 or More than two hop implement by more than one Chapar switch device!
    32  	var i uint8
    33  	for i = 1; i < 255; i++ {
    34  		xp.pathsPool[i] = make([]*routerConnection, 2048)
    35  	}
    36  
    37  	// TODO::: use existing XP number instead of below 1024 number
    38  	xp.XPsPool = make([]*xpPool, 1024)
    39  	xp.XPsPoolLen = 1024
    40  }
    41  
    42  func (xp *xpConnections) expandPathPool(hopNum uint8) (newPoolLen uint32) {
    43  	var poolLen uint32 = uint32(len(xp.pathsPool[hopNum]))
    44  	newPoolLen = poolLen * 2
    45  
    46  	var new = make([]*routerConnection, newPoolLen)
    47  
    48  	// Copy old paths
    49  	var existingConn *routerConnection
    50  	var loc uint32
    51  	var i uint32
    52  	for i = 0; i < poolLen; i++ {
    53  		existingConn = xp.pathsPool[hopNum][i]
    54  		if existingConn != nil {
    55  			loc = crc32.ChecksumIEEE(existingConn.Path) % newPoolLen
    56  			new[loc] = existingConn
    57  		}
    58  	}
    59  	xp.pathsPool[hopNum] = new
    60  
    61  	return
    62  }
    63  
    64  func (xp *xpConnections) expandXPsPool() {
    65  	var newPoolLen uint32 = xp.XPsPoolLen * 2
    66  	var new = make([]*xpPool, newPoolLen)
    67  
    68  	// Copy old XPs
    69  	var eXPPool *xpPool
    70  	var loc uint32
    71  	var i uint32
    72  	for i = 0; i < xp.XPsPoolLen; i++ {
    73  		eXPPool = xp.XPsPool[i]
    74  		if eXPPool != nil {
    75  			loc = eXPPool.XPID % newPoolLen
    76  			new[loc] = eXPPool
    77  		}
    78  	}
    79  
    80  	xp.XPsPool = new
    81  	xp.XPsPoolLen = newPoolLen
    82  }
    83  
    84  // registerNewPath use to register or overwrite a path in the related pool!
    85  func (xp *xpConnections) registerNewPath(conn *routerConnection, path []byte) {
    86  	var pathLen uint8 = uint8(len(conn.Path))
    87  	var poolLen uint32 = uint32(len(xp.pathsPool[pathLen]))
    88  	var loc = crc32.ChecksumIEEE(conn.Path) % poolLen
    89  
    90  	// Check collision!!
    91  	var existingConn = xp.pathsPool[pathLen][loc]
    92  	if existingConn != nil && existingConn.RouterID != conn.RouterID {
    93  		poolLen = xp.expandPathPool(pathLen)
    94  		loc = crc32.ChecksumIEEE(conn.Path) % poolLen
    95  	}
    96  
    97  	xp.pathsPool[pathLen][loc] = conn
    98  }
    99  
   100  // registerNewRouter use to register or overwrite a router in the related pool!
   101  func (xp *xpConnections) registerNewRouter(conn *routerConnection) {
   102  	var eXPPool = xp.GetXPPool(conn.XPID)
   103  	if eXPPool != nil {
   104  		if eXPPool.XPID == conn.XPID {
   105  			for i := 0; i < 8; i++ {
   106  				// Check for existing connection
   107  				if eXPPool.RouterID[i] == conn.RouterID {
   108  					eXPPool.Conn[i].AlternativePath = append(eXPPool.Conn[i].AlternativePath, conn.Path)
   109  					xp.registerNewPath(eXPPool.Conn[i], conn.Path)
   110  				} else if eXPPool.RouterID[i] == 0 {
   111  					eXPPool.FreeID++
   112  					eXPPool.RouterID[i] = conn.RouterID
   113  					eXPPool.Conn[i] = conn
   114  					return
   115  				}
   116  			}
   117  		} else {
   118  			// Collision occurred!!
   119  			xp.expandXPsPool()
   120  			xp.registerNewRouter(conn)
   121  		}
   122  	} else {
   123  		eXPPool = &xpPool{
   124  			XPID:     conn.XPID,
   125  			FreeID:   1,
   126  			RouterID: [8]uint32{conn.RouterID, 0, 0, 0, 0, 0, 0, 0},
   127  			Conn:     [8]*routerConnection{conn, nil, nil, nil, nil, nil, nil, nil},
   128  		}
   129  		var xpLoc = conn.XPID % xp.XPsPoolLen
   130  		xp.XPsPool[xpLoc] = eXPPool
   131  	}
   132  }
   133  
   134  // MakeNewXPConnectionReq is the request structure of MakeNewXPConnection()
   135  type MakeNewXPConnectionReq struct {
   136  	XPID         uint32
   137  	RouterID     uint32
   138  	Path         []byte
   139  	MaxBandwidth uint64
   140  	Signature    [256]byte
   141  }
   142  
   143  // MakeNewXPConnection use to make new connection!
   144  func (xp *xpConnections) MakeNewXPConnection(req *MakeNewXPConnectionReq) {
   145  	// TODO::: Check signature first!
   146  
   147  	var conn = routerConnection{
   148  		RouterID:     req.RouterID,
   149  		Path:         req.Path,
   150  		ReversePath:  chapar.ReversePath(req.Path),
   151  		Status:       routerConnectionStateOpen,
   152  		MaxBandwidth: req.MaxBandwidth,
   153  		Cipher:       crypto.NewGCM(crypto.NewAES256([32]byte{})),
   154  	}
   155  	xp.RegisterConnection(&conn)
   156  }
   157  
   158  // RegisterConnection use to register new connection in server xpConnections pool!!
   159  func (xp *xpConnections) RegisterConnection(conn *routerConnection) {
   160  	xp.registerNewPath(conn, conn.Path)
   161  	xp.registerNewRouter(conn)
   162  }
   163  
   164  // GetConnectionByPath use to get a connection by peer GP from xpConnections pool!!
   165  func (xp *xpConnections) GetConnectionByPath(path []byte) (conn *routerConnection) {
   166  	var pathLen = len(path)
   167  	var poolLen uint32 = uint32(len(xp.pathsPool[pathLen]))
   168  	var loc = crc32.ChecksumIEEE(path) % poolLen
   169  
   170  	conn = xp.pathsPool[pathLen][loc]
   171  	return
   172  }
   173  
   174  // GetConnectionByXPID use to get a connection by given XP ID from xpConnections pool!!
   175  func (xp *xpConnections) GetXPPool(xpID uint32) (eXPPool *xpPool) {
   176  	var xpLoc = xpID % xp.XPsPoolLen
   177  	eXPPool = xp.XPsPool[xpLoc]
   178  	return
   179  }
   180  
   181  // GetConnectionByXPID use to get a connection by given XP ID from xpConnections pool!!
   182  func (xp *xpConnections) GetConnectionByXPID(xpID uint32) (conn *routerConnection) {
   183  	var xpLoc = xpID % xp.XPsPoolLen
   184  	conn = xp.XPsPool[xpLoc].Conn[0]
   185  
   186  	// check if connection is in not ready status
   187  
   188  	return
   189  }
   190  
   191  // CloseConnection use to un-register existing connection in xpConnections pool!!
   192  func (xp *xpConnections) CloseConnection(conn *routerConnection) {
   193  	// TODO::: Check GC performance : delete connection vs just reset it and send it to pool of unused connection!!
   194  	var pathLen = len(conn.Path)
   195  	var poolLen uint32 = uint32(len(xp.pathsPool[pathLen]))
   196  	var loc = crc32.ChecksumIEEE(conn.Path) % poolLen
   197  	var xpLoc = conn.XPID % xp.XPsPoolLen
   198  
   199  	xp.pathsPool[pathLen][loc] = nil
   200  
   201  	var i uint8
   202  	var f = xp.XPsPool[xpLoc].FreeID
   203  	var eXPPool = xp.XPsPool[xpLoc]
   204  	for ; i < f; i++ {
   205  		if eXPPool.RouterID[i] == conn.RouterID {
   206  			eXPPool.RouterID[i] = 0
   207  			eXPPool.Conn[i] = nil
   208  			break
   209  		}
   210  	}
   211  }