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 }