github.com/geniusesgroup/libgo@v0.0.0-20220713101832-828057a9d3d4/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  }