github.com/GeniusesGroup/libgo@v0.0.0-20220929090155-5ff932cb408e/chapar/connection.go (about) 1 /* For license and copyright information please see LEGAL file in repository */ 2 3 package chapar 4 5 import ( 6 "bytes" 7 8 etime "../earth-time" 9 "../protocol" 10 ) 11 12 // Connection ---Read locale description in chaparConnectionStructure--- 13 type Connection struct { 14 writeTime etime.Time 15 16 /* Connection data */ 17 state protocol.ConnectionState 18 weight protocol.ConnectionWeight 19 port *port `syllab:"-"` 20 mtu int 21 pathToPeer Path 22 23 /* Peer data */ 24 pathFromPeer Path // Chapar switch spec 25 alternativePaths []Path 26 thingID [32]byte 27 28 /* Metrics data */ 29 lastUsage etime.Time // Last use of this connection 30 bytesSent uint64 // Counts the bytes of frames payload sent. 31 framesSent uint64 // Counts sent frames. 32 bytesReceived uint64 // Counts the bytes of frames payloads received. 33 framesReceived uint64 // Counts received frames. 34 failedFramesSent uint64 // Counts failed frames receive for firewalling server from some attack types! 35 failedFramesReceived uint64 // Counts failed frames receive for firewalling server from some attack types! 36 notRequestedFramesReceived uint64 // Counts not requested frames received for firewalling server from some attack types! 37 } 38 39 // init set Path, ReversePath and set MTU by calculate it! 40 func (c *Connection) init(frame []byte) (err protocol.Error) { 41 var pathFromPeer Path 42 pathFromPeer.CopyFrom(frame) 43 c.setPath(pathFromPeer) 44 45 // TODO::: Get ThingID from peer?? 46 } 47 48 // MTU return max payload size that this connection can carry on active path! 49 func (c *Connection) MTU() int { 50 return c.mtu 51 } 52 53 // Send use for 54 func (c *Connection) Send(nexHeaderID protocol.NetworkLinkNextHeaderID, payload protocol.Codec) (err protocol.Error) { 55 var payloadLen int = payload.Len() 56 57 // TODO::: need to check path exist here to use c.AlternativePath? 58 59 frame = c.newFrame(nexHeaderID, payload, payloadLen) 60 61 // send frame by connection port! 62 err = c.port.Send(frame) 63 64 // Add metrics data 65 c.lastUsage = etime.Now() 66 if err != nil { 67 c.failedFramesSent++ 68 } else { 69 c.bytesSent += uint64(payloadLen) 70 c.framesSent++ 71 } 72 return 73 } 74 75 // SendAsync use to send the frame async! 76 func (c *Connection) SendAsync(nexHeaderID protocol.NetworkLinkNextHeaderID, payload protocol.Codec) (err protocol.Error) { 77 var payloadLen int = payload.Len() 78 79 // TODO::: need to check path exist here to use c.AlternativePath? 80 81 frame = c.newFrame(nexHeaderID, payload, payloadLen) 82 83 // send frame by connection port! 84 err = c.port.SendAsync(frame) 85 86 // Add metrics data 87 c.lastUsage = etime.Now() 88 c.bytesSent += uint64(payloadLen) 89 c.framesSent++ 90 return 91 } 92 93 // newFrame makes new unicast||broadcast frame! 94 func (c *Connection) newFrame(nexHeaderID protocol.NetworkLinkNextHeaderID, payload protocol.Codec, payloadLen int) (frame []byte) { 95 if payloadLen > c.mtu { 96 return ErrMTU 97 } 98 99 var pathLen byte = c.pathToPeer.LenAsByte() 100 var payloadLoc int = 3 + int(pathLen) 101 var frameLength int = payloadLoc + payloadLen 102 frame = make([]byte, frameLength) 103 104 SetHopCount(frame, pathLen) 105 SetNextHeader(frame, byte(nexHeaderID)) 106 c.pathToPeer.MarshalTo(frame) 107 payload.MarshalTo(frame[payloadLoc:]) 108 return 109 } 110 111 // setPath set Path, ReversePath and set MTU by calculate it! 112 func (c *Connection) setPath(pathFromPeer Path) { 113 c.pathFromPeer = pathFromPeer 114 c.pathToPeer = pathFromPeer.GetReverse() 115 c.mtu = MaxFrameLen - int(FixedHeaderLength+pathFromPeer.LenAsByte()) 116 } 117 118 // setAlternativePath register connection new path in the connection alternativePaths! 119 func (c *Connection) setAlternativePath(alternativePath Path) (err protocol.Error) { 120 for path := range c.alternativePaths { 121 if bytes.Equal(path, alternativePath) { 122 err = ErrPathAlreadyExist 123 return 124 } 125 } 126 c.alternativePaths = append(c.alternativePaths, alternativePath) 127 return 128 } 129 130 // ChangePath change the main connection path! 131 func (c *Connection) changePath(pathFromPeer Path) (err protocol.Error) { 132 if bytes.Equal(c.pathFromPeer, pathFromPeer) { 133 err = ErrPathAlreadyUse 134 return 135 } 136 c.setAlternativePath(c.pathFromPeer) 137 c.setPath(pathFromPeer) 138 return 139 }