mirror of
https://github.com/PretendoNetwork/nex-go.git
synced 2025-04-02 11:02:14 -04:00
201 lines
5.7 KiB
Go
201 lines
5.7 KiB
Go
package nex
|
|
|
|
import (
|
|
"crypto/rc4"
|
|
|
|
"github.com/PretendoNetwork/nex-go/v2/constants"
|
|
)
|
|
|
|
// PRUDPPacket holds all the fields each packet should have in all PRUDP versions
|
|
type PRUDPPacket struct {
|
|
server *PRUDPServer
|
|
sender *PRUDPConnection
|
|
readStream *ByteStreamIn
|
|
version uint8
|
|
sourceVirtualPort VirtualPort
|
|
destinationVirtualPort VirtualPort
|
|
packetType uint16
|
|
flags uint16
|
|
sessionID uint8
|
|
substreamID uint8
|
|
signature []byte
|
|
sequenceID uint16
|
|
connectionSignature []byte
|
|
fragmentID uint8
|
|
payload []byte
|
|
message *RMCMessage
|
|
}
|
|
|
|
// SetSender sets the Client who sent the packet
|
|
func (p *PRUDPPacket) SetSender(sender ConnectionInterface) {
|
|
p.sender = sender.(*PRUDPConnection)
|
|
}
|
|
|
|
// Sender returns the Client who sent the packet
|
|
func (p *PRUDPPacket) Sender() ConnectionInterface {
|
|
return p.sender
|
|
}
|
|
|
|
// Flags returns the packet flags
|
|
func (p *PRUDPPacket) Flags() uint16 {
|
|
return p.flags
|
|
}
|
|
|
|
// HasFlag checks if the packet has the given flag
|
|
func (p *PRUDPPacket) HasFlag(flag uint16) bool {
|
|
return p.flags&flag != 0
|
|
}
|
|
|
|
// AddFlag adds the given flag to the packet flag bitmask
|
|
func (p *PRUDPPacket) AddFlag(flag uint16) {
|
|
p.flags |= flag
|
|
}
|
|
|
|
// SetType sets the packets type
|
|
func (p *PRUDPPacket) SetType(packetType uint16) {
|
|
p.packetType = packetType
|
|
}
|
|
|
|
// Type returns the packets type
|
|
func (p *PRUDPPacket) Type() uint16 {
|
|
return p.packetType
|
|
}
|
|
|
|
// SetSourceVirtualPortStreamType sets the packets source VirtualPort StreamType
|
|
func (p *PRUDPPacket) SetSourceVirtualPortStreamType(streamType constants.StreamType) {
|
|
p.sourceVirtualPort.SetStreamType(streamType)
|
|
}
|
|
|
|
// SourceVirtualPortStreamType returns the packets source VirtualPort StreamType
|
|
func (p *PRUDPPacket) SourceVirtualPortStreamType() constants.StreamType {
|
|
return p.sourceVirtualPort.StreamType()
|
|
}
|
|
|
|
// SetSourceVirtualPortStreamID sets the packets source VirtualPort port number
|
|
func (p *PRUDPPacket) SetSourceVirtualPortStreamID(port uint8) {
|
|
p.sourceVirtualPort.SetStreamID(port)
|
|
}
|
|
|
|
// SourceVirtualPortStreamID returns the packets source VirtualPort port number
|
|
func (p *PRUDPPacket) SourceVirtualPortStreamID() uint8 {
|
|
return p.sourceVirtualPort.StreamID()
|
|
}
|
|
|
|
// SetDestinationVirtualPortStreamType sets the packets destination VirtualPort StreamType
|
|
func (p *PRUDPPacket) SetDestinationVirtualPortStreamType(streamType constants.StreamType) {
|
|
p.destinationVirtualPort.SetStreamType(streamType)
|
|
}
|
|
|
|
// DestinationVirtualPortStreamType returns the packets destination VirtualPort StreamType
|
|
func (p *PRUDPPacket) DestinationVirtualPortStreamType() constants.StreamType {
|
|
return p.destinationVirtualPort.StreamType()
|
|
}
|
|
|
|
// SetDestinationVirtualPortStreamID sets the packets destination VirtualPort port number
|
|
func (p *PRUDPPacket) SetDestinationVirtualPortStreamID(port uint8) {
|
|
p.destinationVirtualPort.SetStreamID(port)
|
|
}
|
|
|
|
// DestinationVirtualPortStreamID returns the packets destination VirtualPort port number
|
|
func (p *PRUDPPacket) DestinationVirtualPortStreamID() uint8 {
|
|
return p.destinationVirtualPort.StreamID()
|
|
}
|
|
|
|
// SessionID returns the packets session ID
|
|
func (p *PRUDPPacket) SessionID() uint8 {
|
|
return p.sessionID
|
|
}
|
|
|
|
// SetSessionID sets the packets session ID
|
|
func (p *PRUDPPacket) SetSessionID(sessionID uint8) {
|
|
p.sessionID = sessionID
|
|
}
|
|
|
|
// SubstreamID returns the packets substream ID
|
|
func (p *PRUDPPacket) SubstreamID() uint8 {
|
|
return p.substreamID
|
|
}
|
|
|
|
// SetSubstreamID sets the packets substream ID
|
|
func (p *PRUDPPacket) SetSubstreamID(substreamID uint8) {
|
|
p.substreamID = substreamID
|
|
}
|
|
|
|
func (p *PRUDPPacket) setSignature(signature []byte) {
|
|
p.signature = signature
|
|
}
|
|
|
|
// SequenceID returns the packets sequenc ID
|
|
func (p *PRUDPPacket) SequenceID() uint16 {
|
|
return p.sequenceID
|
|
}
|
|
|
|
// SetSequenceID sets the packets sequenc ID
|
|
func (p *PRUDPPacket) SetSequenceID(sequenceID uint16) {
|
|
p.sequenceID = sequenceID
|
|
}
|
|
|
|
// Payload returns the packets payload
|
|
func (p *PRUDPPacket) Payload() []byte {
|
|
return p.payload
|
|
}
|
|
|
|
// SetPayload sets the packets payload
|
|
func (p *PRUDPPacket) SetPayload(payload []byte) {
|
|
p.payload = payload
|
|
}
|
|
|
|
func (p *PRUDPPacket) decryptPayload() []byte {
|
|
payload := p.payload
|
|
|
|
// TODO - This assumes a reliable DATA packet. Handle unreliable here? Or do that in a different method?
|
|
if p.packetType == constants.DataPacket {
|
|
slidingWindow := p.sender.SlidingWindow(p.SubstreamID())
|
|
|
|
payload, _ = slidingWindow.streamSettings.EncryptionAlgorithm.Decrypt(payload)
|
|
}
|
|
|
|
return payload
|
|
}
|
|
|
|
func (p *PRUDPPacket) getConnectionSignature() []byte {
|
|
return p.connectionSignature
|
|
}
|
|
|
|
func (p *PRUDPPacket) setConnectionSignature(connectionSignature []byte) {
|
|
p.connectionSignature = connectionSignature
|
|
}
|
|
|
|
func (p *PRUDPPacket) getFragmentID() uint8 {
|
|
return p.fragmentID
|
|
}
|
|
|
|
func (p *PRUDPPacket) setFragmentID(fragmentID uint8) {
|
|
p.fragmentID = fragmentID
|
|
}
|
|
|
|
// RMCMessage returns the packets RMC Message
|
|
func (p *PRUDPPacket) RMCMessage() *RMCMessage {
|
|
return p.message
|
|
}
|
|
|
|
// SetRMCMessage sets the packets RMC Message
|
|
func (p *PRUDPPacket) SetRMCMessage(message *RMCMessage) {
|
|
p.message = message
|
|
}
|
|
|
|
func (p *PRUDPPacket) processUnreliableCrypto() []byte {
|
|
// * Since unreliable DATA packets can come in out of
|
|
// * order, each packet uses a dedicated RC4 stream
|
|
uniqueKey := p.sender.UnreliablePacketBaseKey[:]
|
|
uniqueKey[0] = byte((uint16(uniqueKey[0]) + p.sequenceID) & 0xFF)
|
|
uniqueKey[1] = byte((uint16(uniqueKey[1]) + (p.sequenceID >> 8)) & 0xFF)
|
|
uniqueKey[31] = byte((uniqueKey[31] + p.sessionID) & 0xFF)
|
|
|
|
cipher, _ := rc4.NewCipher(uniqueKey)
|
|
ciphered := make([]byte, len(p.payload))
|
|
|
|
cipher.XORKeyStream(ciphered, p.payload)
|
|
|
|
return ciphered
|
|
}
|