github.com/iDigitalFlame/xmt@v0.5.4/c2/types.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 c2 18 19 import ( 20 "context" 21 "net" 22 "sort" 23 "time" 24 25 "github.com/iDigitalFlame/xmt/c2/cfg" 26 "github.com/iDigitalFlame/xmt/c2/cout" 27 "github.com/iDigitalFlame/xmt/com" 28 "github.com/iDigitalFlame/xmt/util/bugtrack" 29 "github.com/iDigitalFlame/xmt/util/xerr" 30 ) 31 32 const fragMaxMisses = 5 33 34 var wake struct{} 35 36 type event struct { 37 s *Session 38 p *com.Packet 39 j *Job 40 jf func(*Job) 41 sf func(*Session) 42 pf func(*com.Packet) 43 af func(*com.Packet) bool 44 hf func(*Session, *com.Packet) bool 45 } 46 type cluster struct { 47 data []*com.Packet 48 max uint16 49 e uint16 50 c uint8 51 } 52 type proxyData struct { 53 n, b string 54 p []byte 55 } 56 type eventer chan event 57 type connection struct { 58 _ [0]func() 59 s *Server 60 w cfg.Wrapper 61 t cfg.Transform 62 m messager 63 p cfg.Profile 64 ctx context.Context 65 log cout.Log 66 } 67 type messager interface { 68 close() 69 count() int 70 queue(event) 71 } 72 type runnable interface { 73 Pid() uint32 74 Start() error 75 Release() error 76 } 77 type notifier interface { 78 accept(uint16) 79 frag(uint16, uint16, uint16, uint16) 80 } 81 type marshaler interface { 82 MarshalBinary() (data []byte, err error) 83 } 84 type readerTimeout struct { 85 _ [0]func() 86 c net.Conn 87 t time.Duration 88 i bool 89 } 90 91 func (e eventer) close() { 92 close(e) 93 } 94 func (c *cluster) Len() int { 95 return len(c.data) 96 } 97 func (e eventer) count() int { 98 return len(e) 99 } 100 func (e eventer) queue(x event) { 101 e <- x 102 } 103 func (c *cluster) Swap(i, j int) { 104 c.data[i], c.data[j] = c.data[j], c.data[i] 105 } 106 func (e eventer) listen(s *Session) { 107 if bugtrack.Enabled { 108 defer bugtrack.Recover("c2.eventer.listen()") 109 } 110 if cout.Enabled { 111 s.log.Debug("Client-side event processing thread started!") 112 } 113 for { 114 select { 115 case <-s.ctx.Done(): 116 s.Close() 117 return 118 case v := <-e: 119 v.process(s.log) 120 } 121 } 122 } 123 func (e event) process(l cout.Log) { 124 defer func() { 125 if err := recover(); err != nil { 126 if cout.Enabled { 127 l.Error("Server event processing function recovered from a panic: %s!", err) 128 } 129 } 130 }() 131 switch { 132 case e.af != nil && e.p != nil && e.s != nil: // Direct client side packet handler. 133 if e.af(e.p) && e.s.Receive == nil { // Handled and Receive is nil, clear and break. 134 break 135 } 136 if e.s.Receive != nil { // If Receive is not nil, call it then break. 137 e.s.Receive(e.s, e.p) 138 break 139 } 140 if e.s.recv != nil && e.s.state.CanRecv() { // If there's a receive channel setup, use that. 141 select { 142 case e.s.recv <- e.p: 143 default: 144 if cout.Enabled { 145 l.Warning(`[%s] Packet "%s" was dropped during receive!`, e.s.ID, e.p) 146 } 147 } 148 break 149 } 150 e.p.Clear() // Otherwise, clear the packet. 151 case e.hf != nil && e.p != nil && e.s != nil: // Mux packet handler. 152 if e.hf(e.s, e.p) && e.s.Receive == nil { 153 break 154 } 155 if e.s.Receive != nil { 156 e.s.Receive(e.s, e.p) 157 break 158 } 159 if e.s.recv != nil && e.s.state.CanRecv() { 160 select { 161 case e.s.recv <- e.p: 162 default: 163 if cout.Enabled { 164 l.Warning(`[%s] Packet "%s" was dropped during receive!`, e.s.ID, e.p) 165 } 166 } 167 break 168 } 169 e.p.Clear() 170 case e.pf != nil && e.p != nil: // Oneshot handler 171 e.pf(e.p) 172 case e.sf != nil && e.s != nil: // Session New or Shutdown handler. 173 e.sf(e.s) 174 case e.jf != nil && e.j != nil: // Job Update handler 175 e.jf(e.j) 176 } 177 } 178 func (c *cluster) done() *com.Packet { 179 if len(c.data) == 0 { 180 return nil 181 } 182 if uint16(len(c.data)) > (c.max + c.e) { 183 sort.Sort(c) 184 n := c.data[0] 185 for x := 1; x < len(c.data); x++ { 186 n.Add(c.data[x]) 187 c.data[x].Clear() 188 c.data[x] = nil 189 } 190 c.data = nil 191 n.Flags.Clear() 192 return n 193 } 194 return nil 195 } 196 func (c *cluster) Less(i, j int) bool { 197 return c.data[i].Flags.Position() < c.data[j].Flags.Position() 198 } 199 func (c *cluster) add(p *com.Packet) error { 200 if p == nil { 201 c.c = fragMaxMisses 202 return nil 203 } 204 if len(c.data) > 0 && !c.data[0].Belongs(p) { 205 return xerr.Sub("packet ID does not match the supplied ID", 0x52) 206 } 207 c.c = fragMaxMisses 208 if c.max = p.Flags.Len() - 1; p.Empty() { 209 c.e++ 210 return nil 211 } 212 c.data = append(c.data, p) 213 return nil 214 } 215 func (r *readerTimeout) Read(b []byte) (int, error) { 216 if r.i { 217 r.c.SetReadDeadline(time.Now().Add(r.t)) 218 } else { 219 r.i = true 220 } 221 return r.c.Read(b) 222 }