items returns the live list of settings bound to the active profile. Called on every View so changes in the config (via external edit) show up.
()
| 33 | // items returns the live list of settings bound to the active profile. |
| 34 | // Called on every View so changes in the config (via external edit) show up. |
| 35 | func (m *settingsModel) items() []settingItem { |
| 36 | cfg := m.app.cfg |
| 37 | if cfg == nil { |
| 38 | return nil |
| 39 | } |
| 40 | p, ok := cfg.Lookup(cfg.Active) |
| 41 | if !ok { |
| 42 | return nil |
| 43 | } |
| 44 | return []settingItem{ |
| 45 | { |
| 46 | label: "Randomize timing", |
| 47 | value: boolStr(p.Spoof.RandomizeTiming), |
| 48 | help: "Jitters the fake-packet inject delay in [MinDelay, MaxDelay] so\ndelay isn't a DPI fingerprint.", |
| 49 | toggle: func() { p.Spoof.RandomizeTiming = !p.Spoof.RandomizeTiming }, |
| 50 | }, |
| 51 | { |
| 52 | label: "Randomize padding", |
| 53 | value: boolStr(p.Spoof.RandomizePadding), |
| 54 | help: "Varies fake ClientHello size in [517, 517+MaxExtraPad]. Breaks the\nfixed-517-byte pattern used by upstream pydivert.", |
| 55 | toggle: func() { p.Spoof.RandomizePadding = !p.Spoof.RandomizePadding }, |
| 56 | }, |
| 57 | { |
| 58 | label: "Strategy rotation", |
| 59 | value: rotationLabel(p.Spoof.StrategyRotation), |
| 60 | help: "Cycles bypass strategies per flow. Common rotation pairs wrong_seq\nwith wrong_checksum so the DPI can't learn a single packet shape.", |
| 61 | toggle: func() { |
| 62 | if len(p.Spoof.StrategyRotation) == 0 { |
| 63 | p.Spoof.StrategyRotation = []bypass.Name{bypass.NameWrongSeq, bypass.NameWrongChecksum} |
| 64 | } else { |
| 65 | p.Spoof.StrategyRotation = nil |
| 66 | } |
| 67 | }, |
| 68 | }, |
| 69 | { |
| 70 | label: "IP ID delta range", |
| 71 | value: fmt.Sprintf("%d", maxOne(p.Spoof.IPIDDeltaRange)), |
| 72 | help: "Random delta applied to the fake packet's IP identification field.\n1 = upstream behaviour; higher = more variance. Press +/- to adjust.", |
| 73 | toggle: func() {}, // handled by numeric keys below |
| 74 | }, |
| 75 | { |
| 76 | label: "SNI selection", |
| 77 | value: fallback(p.Spoof.SNISelection, "random"), |
| 78 | help: "random (default): pick a new SNI per flow uniformly at random.\nround_robin: deterministic cycle through sni_pool.", |
| 79 | toggle: func() { |
| 80 | if p.Spoof.SNISelection == "round_robin" { |
| 81 | p.Spoof.SNISelection = "random" |
| 82 | } else { |
| 83 | p.Spoof.SNISelection = "round_robin" |
| 84 | } |
| 85 | }, |
| 86 | }, |
| 87 | } |
| 88 | } |
| 89 | |
| 90 | func (m settingsModel) Init() tea.Cmd { return nil } |
| 91 |