github.com/GeniusesGroup/libgo@v0.0.0-20220929090155-5ff932cb408e/gp/stream.go (about)

     1  /* For license and copyright information please see LEGAL file in repository */
     2  
     3  package gp
     4  
     5  import (
     6  	etime "../earth-time"
     7  	"../protocol"
     8  )
     9  
    10  // Stream use to send or receive data on specific connection.
    11  // It can pass to logic layer to give data access to developer!
    12  // Data flow can be up to down (parse raw income data) or down to up (encode app data with respect MTU)
    13  // If OutcomePayload not present stream is UnidirectionalStream otherwise it is BidirectionalStream!
    14  type Stream struct {
    15  	id          uint32 // Even number for Peer(who start connection). Odd number for server(who accept connection).
    16  	connection  *Connection
    17  	protocolID  protocol.NetworkApplicationProtocolID
    18  	service     protocol.Service
    19  	incomeData  protocol.Codec
    20  	outcomeData protocol.Codec
    21  
    22  	/* State */
    23  	status protocol.ConnectionState      // States locate in const of this file.
    24  	state  chan protocol.ConnectionState // States locate in const of this file.
    25  	Weight protocol.ConnectionWeight     // 16 queue for priority weight of the streams exist.
    26  
    27  	/* Metrics */
    28  	TotalPacket     uint32 // Expected packets count that must received!
    29  	PacketReceived  uint32 // Count of packets received!
    30  	LastPacketID    uint32 // Last send or received Packet use to know order of packets!
    31  	PacketDropCount uint8  // Count drop packets to prevent some attacks type!
    32  }
    33  
    34  func (st *Stream) ID() uint32                                        { return st.id }
    35  func (st *Stream) Connection() protocol.Connection                   { return st.connection }
    36  func (st *Stream) Service() protocol.Service                         { return st.service }
    37  func (st *Stream) ProtocolID() protocol.NetworkApplicationProtocolID { return st.protocolID }
    38  func (st *Stream) Status() protocol.ConnectionState                  { return st.status }
    39  func (st *Stream) State() chan protocol.ConnectionState              { return st.state }
    40  func (st *Stream) IncomeData() protocol.Codec                        { return st.incomeData }
    41  func (st *Stream) OutcomeData() protocol.Codec                       { return st.outcomeData }
    42  func (st *Stream) SetIncomeData(codec protocol.Codec)                { st.incomeData = codec }
    43  func (st *Stream) SetOutcomeData(codec protocol.Codec)               { st.outcomeData = codec }
    44  
    45  // SetService check and if it is first time register given service for the stream.
    46  func (st *Stream) SetService(service protocol.Service) {
    47  	if st.service != nil {
    48  		st.service = service
    49  	}
    50  }
    51  
    52  
    53  // SendRequest use for default and empty switch port due to non of ports can be nil!
    54  // SendAndWait register stream in send pool and block caller until response ready to read.
    55  func (st *Stream) SendRequest() (err protocol.Error) {
    56  	
    57  	var outcomeData = stream.OutcomeData()
    58  	if outcomeData != nil {
    59  	}
    60  	
    61  	// st.Send()
    62  
    63  	// Listen to response stream and decode error ID and return it to caller
    64  	var responseStatus protocol.ConnectionState = <-st.State()
    65  	if responseStatus == protocol.ConnectionStateReady {
    66  
    67  	} else {
    68  
    69  	}
    70  
    71  	// Last Close response stream!
    72  	st.Close()
    73  	return
    74  }
    75  
    76  // SendResponse register stream in send pool. Usually use to send response stream.
    77  func (st *Stream) SendResponse() (err protocol.Error) {
    78  	// First Check st.Connection.Status to ability send stream over it
    79  
    80  	// TODO::: remove this check when remove IP support
    81  	// if st.Connection.IPAddr != [16]byte{} {
    82  	// Send by IP
    83  	// } else {
    84  	// Send stream by GP
    85  	// }
    86  
    87  	// send stream by weight
    88  
    89  	/* Metrics data */
    90  	// c.BytesSent += uint64(len(st.OutcomePayload))
    91  
    92  	// Last Close stream!
    93  	st.Close()
    94  	return
    95  }
    96  
    97  // CloseStream delete given Stream from pool
    98  func (st *Stream) Close() {
    99  	sp.mutex.Lock()
   100  	delete(st.connection.StreamPool.p, st.id)
   101  	sp.mutex.Unlock()
   102  }
   103  
   104  // SetState change state of stream and send notification on stream StateChannel.
   105  func (st *Stream) SetState(state protocol.ConnectionState) {
   106  	// atomic.StoreUInt64(&st.State, state)
   107  	st.State = state
   108  	// notify stream listener that stream state has been changed!
   109  	st.StateChannel <- state
   110  }
   111  
   112  // Authorize authorize request by data in related stream and connection.
   113  func (st *Stream) Authorize() (err protocol.Error) {
   114  	// if st.Connection().UserID() != protocol.OS.AppManifest().AppUUID() {
   115  	// 	// TODO::: Attack??
   116  	// 	err = ErrNotAuthorizeRequest
   117  	// 	return
   118  	// }
   119  
   120  	err = st.Service.Authorization.UserType.Check(st.Connection.UserType)
   121  	if err != nil {
   122  		return
   123  	}
   124  
   125  	err = st.Connection.AccessControl.AuthorizeWhen(etime.Now().Weekdays(), etime.Now().DayHours())
   126  	if err != nil {
   127  		return
   128  	}
   129  	err = st.Connection.AccessControl.AuthorizeWhich(st.Service.ID, st.Service.Authorization.CRUD)
   130  	if err != nil {
   131  		return
   132  	}
   133  	err = st.Connection.AccessControl.AuthorizeWhere(st.Connection.GPAddr.GetSocietyID(), st.Connection.GPAddr.GetRouterID())
   134  	if err != nil {
   135  		return
   136  	}
   137  	return
   138  }
   139  
   140  // MakeNewStream use to make new stream without any connection exist yet!
   141  // TODO::: due to IPv4&&IPv6 support we need this func! Remove it when remove those support!
   142  func MakeNewStream() (st *Stream, err protocol.Error) {
   143  	// TODO::: check server allow make new connection and has enough resource
   144  
   145  	st = &Stream{
   146  		// ID:           0,
   147  		State:        protocol.ConnectionStateOpening,
   148  		StateChannel: make(chan protocol.ConnectionState),
   149  	}
   150  	return
   151  }