github.com/iDigitalFlame/xmt@v0.5.4/com/flag.go (about)

     1  // Copyright (C) 2020 - 2023 iDigitalFlame
     2  //
     3  // This program is free software: you can redistribute it and/or modify
     4  // it under the terms of the GNU General Public License as published by
     5  // the Free Software Foundation, either version 3 of the License, or
     6  // any later version.
     7  //
     8  // This program is distributed in the hope that it will be useful,
     9  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    10  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    11  // GNU General Public License for more details.
    12  //
    13  // You should have received a copy of the GNU General Public License
    14  // along with this program.  If not, see <https://www.gnu.org/licenses/>.
    15  //
    16  
    17  package com
    18  
    19  import "github.com/iDigitalFlame/xmt/data"
    20  
    21  const (
    22  	// FlagFrag is a flag used to indicate that the packet is part of a
    23  	// fragment group and the server should re-assemble the packet before
    24  	// preforming actions on it.
    25  	FlagFrag = 1 << iota
    26  	// FlagMulti is a flag used to indicate that the packet is a container
    27  	// for multiple packets, auto added by a processing agent. This Flag also
    28  	// carries the 'FlagFrag' flag.
    29  	FlagMulti
    30  	// FlagProxy is a flag used to indicate that the packet was sent from another
    31  	// client acting as a forwarding proxy.
    32  	FlagProxy
    33  	// FlagError is a flag used to indicate that the packet indicates that an error
    34  	// condition has occurred. The contents of the Packet can be used to
    35  	// understand the error cause.
    36  	FlagError
    37  	// FlagChannel is a flag used to signify that the connection should be converted
    38  	// into/from a single channel connection. This means that the connection is
    39  	// kept alive and the client will not poll the server.
    40  	//
    41  	// This flag will be present on the top level multi-packet if included in a
    42  	// single packet inside. This flag will take effect on each hop that it goes
    43  	// through.
    44  	//
    45  	// Incompatible with 'FlagOneshot'. Can only be used once per single connection.
    46  	FlagChannel
    47  	// FlagChannelEnd is a flag used to signify that a Channel connection should
    48  	// be terminated. Unlike the 'FlagChannel' option, this will only affect the
    49  	// targeted hop.
    50  	//
    51  	// Incompatible with 'FlagOneshot'. Can only be used once per single connection.
    52  	FlagChannelEnd
    53  	// FlagOneshot is used to signal that the Packet contains information and
    54  	// should not be used to create or re-establish a session.
    55  	FlagOneshot
    56  	// FlagMultiDevice is used to determine if the Multi packet contains Packets
    57  	// with separate device IDs. This is used to speed up processing and allows
    58  	// packets that are all destined for the same host to be batch processed.
    59  	FlagMultiDevice
    60  	// FlagCrypt is used to indicate that the Packet is carrying Crypt related
    61  	// information or a side of the conversation is asking for a re-key.
    62  	FlagCrypt
    63  )
    64  
    65  // Flag is a bitwise integer that represents important
    66  // information about the packet that it's assigned to.
    67  //
    68  // Mapping
    69  //
    70  //	| 64     56        48        40        32        24        16         8       0 |
    71  //	| ----------------- | ----------------- | ----------------- | ----------------- |
    72  //	| 8 4 2 1 | 8 4 2 1 | 8 4 2 1 | 8 4 2 1 | 8 4 2 1 | 8 4 2 1 | 8 4 2 1 | 8 4 2 1 |
    73  //	|    Frag Total     |   Frag Position   |   Frag Group ID   |       Flags       |
    74  //	|                         Frag Data                         |                   |
    75  type Flag uint64
    76  
    77  // Clear clears all Frag and Multi related data values.
    78  func (f *Flag) Clear() {
    79  	*f = Flag(uint16(*f)) ^ FlagFrag
    80  }
    81  
    82  // Set appends the Flag value to this current Flag value.
    83  func (f *Flag) Set(n Flag) {
    84  	*f = *f | n
    85  }
    86  
    87  // Len returns the count of fragmented packets that make up this fragment group.
    88  func (f Flag) Len() uint16 {
    89  	return uint16(f >> 48)
    90  }
    91  
    92  // Unset removes the Flag value to this current Flag value.
    93  func (f *Flag) Unset(n Flag) {
    94  	*f = *f &^ n
    95  }
    96  
    97  // Group returns the fragment group ID that this packet is part of.
    98  func (f Flag) Group() uint16 {
    99  	return uint16(f >> 16)
   100  }
   101  
   102  // Position represents position of this packet in a fragment group.
   103  func (f Flag) Position() uint16 {
   104  	return uint16(f >> 32)
   105  }
   106  
   107  // SetLen sets the total count of packets in the fragment group.
   108  func (f *Flag) SetLen(n uint16) {
   109  	*f = Flag(n)<<48 | Flag(f.Position())<<32 | Flag(uint32(*f)) | FlagFrag
   110  }
   111  
   112  // SetGroup sets the group ID of the fragment group this packet is part of.
   113  func (f *Flag) SetGroup(n uint16) {
   114  	*f = ((*f >> 32) << 32) | Flag(n)<<16 | Flag(uint16(*f)) | FlagFrag
   115  }
   116  
   117  // SetPosition sets the position this packet is located in the fragment group.
   118  func (f *Flag) SetPosition(n uint16) {
   119  	*f = Flag(f.Len())<<48 | Flag(n)<<32 | Flag(uint32(*f)) | FlagFrag
   120  }
   121  
   122  // MarshalStream writes the data of this Flag to the supplied Writer.
   123  func (f Flag) MarshalStream(w data.Writer) error {
   124  	return w.WriteUint64(uint64(f))
   125  }
   126  
   127  // UnmarshalStream reads the data of this Flag from the supplied Reader.
   128  func (f *Flag) UnmarshalStream(r data.Reader) error {
   129  	return r.ReadUint64((*uint64)(f))
   130  }