scheduleInject sleeps the randomizer-chosen delay then emits the spoofed packet. The ACK that triggered us is passed by value so we can build the injection even if the original buffer has been released.
(conn *conntrack.Connection, ack pkt, synSeq uint32, fakeData []byte, fs *flowState)
| 268 | // packet. The ACK that triggered us is passed by value so we can build the |
| 269 | // injection even if the original buffer has been released. |
| 270 | func (e *Engine) scheduleInject(conn *conntrack.Connection, ack pkt, |
| 271 | synSeq uint32, fakeData []byte, fs *flowState) { |
| 272 | |
| 273 | time.Sleep(e.rnd.Delay()) |
| 274 | |
| 275 | strat, _ := bypass.ByName(fs.strategy) // validated at New() time |
| 276 | mut, err := strat.Plan(bypass.Inputs{ |
| 277 | SynSeq: synSeq, |
| 278 | FakePayload: fakeData, |
| 279 | }) |
| 280 | if err != nil { |
| 281 | e.warnf("strategy.Plan: %v", err) |
| 282 | return |
| 283 | } |
| 284 | |
| 285 | spec := injectSpec{ |
| 286 | ipIDDelta: fs.delta, |
| 287 | setPSH: mut.SetPSH, |
| 288 | payload: mut.Payload, |
| 289 | corruptChecksum: mut.CorruptChecksum, |
| 290 | } |
| 291 | if mut.OverrideSeq { |
| 292 | spec.seqNum = mut.SeqNum |
| 293 | } else { |
| 294 | spec.seqNum = ack.seqNum |
| 295 | } |
| 296 | |
| 297 | inj := buildInjection(ack, spec) |
| 298 | |
| 299 | conn.Mu.Lock() |
| 300 | if conn.Stage == conntrack.StageAckSent { |
| 301 | conn.Stage = conntrack.StageFakeSent |
| 302 | } |
| 303 | conn.Mu.Unlock() |
| 304 | |
| 305 | if err := e.backend.Inject(inj, platform.DirOutbound); err != nil { |
| 306 | e.warnf("inject: %v", err) |
| 307 | conn.Mu.Lock() |
| 308 | conn.Finish(false, fmt.Sprintf("inject error: %v", err)) |
| 309 | conn.Mu.Unlock() |
| 310 | e.table.Remove(conn.Tuple) |
| 311 | e.flows.Delete(conn.Tuple) |
| 312 | return |
| 313 | } |
| 314 | e.infof("snix: injected %s sni=%s size=%d seq=%#x id_delta=%d", |
| 315 | fs.strategy, fs.sni, len(inj), spec.seqNum, fs.delta) |
| 316 | } |
| 317 | |
| 318 | // newFakeClientHello picks an SNI per the randomizer, builds a ClientHello |
| 319 | // with randomized extra padding, and returns both the bytes and the SNI used |
no test coverage detected