From 4ef0268c4ae266e93a9c7693ed94296d8c71a94b Mon Sep 17 00:00:00 2001 From: Mark Mennell Date: Wed, 1 Apr 2026 17:21:15 +0800 Subject: [PATCH 1/2] flags realigned to latest spec --- TODO.md | 19 ++++++++++----- src/host.go | 66 ++++++++++++++++++----------------------------------- 2 files changed, 35 insertions(+), 50 deletions(-) diff --git a/TODO.md b/TODO.md index c0d9b4b..540e68a 100644 --- a/TODO.md +++ b/TODO.md @@ -7,12 +7,17 @@ correctness issues, then enhancements. ## P0 — Foundational (blocks most other work) -### 1. Realign flag bit assignments to spec +### ~~1. Realign flag bit assignments to spec~~ **File:** `host.go` constants -Current flags are wrong: `FlagImportant` is on bit 1 (spec: bit 3), +~~Current flags are wrong: `FlagImportant` is on bit 1 (spec: bit 3), `FlagNoReply` on bit 3 (spec: bit 4), and `FlagSkipChallenge` (bit 4) does not exist in the spec. Missing: `FlagHasAddTo` (bit 1), `FlagCommonType` (bit 2). -All flag definitions and every usage site must be realigned. +All flag definitions and every usage site must be realigned.~~ +**DONE:** Flags realigned to spec. Added `FlagHasAddTo` (bit 1), `FlagCommonType` (bit 2). +Moved `FlagImportant` to bit 3, `FlagNoReply` to bit 4. Removed `FlagSkipChallenge`. +Removed `RejectCodeMustChallenge`/`RejectCodeCannotChallenge`, added `AcceptCodeHeader` (11), +`RejectCodeUserNotAccepting` (102), `RejectCodeUserUndisclosed` (103). +Fixed `validateMsgRecvForAddr` to return code 102 instead of 100 for non-accepting users. ### 2. Fix `Encode()` to produce the full message header per spec **File:** `defs.go` `Encode()` @@ -41,11 +46,13 @@ Add a `ChallengeCompleted bool` to distinguish "challenge was completed and hash verification check in `downloadMessage` erroneously fails when the challenge was skipped. -### 6. Fix response code constants +### ~~6. Fix response code constants~~ **File:** `host.go` constants -`RejectCodeMustChallenge` (11) and `RejectCodeCannotChallenge` (12) do not +~~`RejectCodeMustChallenge` (11) and `RejectCodeCannotChallenge` (12) do not exist in the spec. Code 11 = "accept header" (add-to notification success). -Add missing per-user codes: 102 (user not accepting), 103 (user undisclosed). +Add missing per-user codes: 102 (user not accepting), 103 (user undisclosed).~~ +**DONE:** Replaced with `AcceptCodeHeader` (11), added `RejectCodeUserNotAccepting` (102) +and `RejectCodeUserUndisclosed` (103). --- diff --git a/src/host.go b/src/host.go index 82346fd..107896b 100644 --- a/src/host.go +++ b/src/host.go @@ -29,18 +29,15 @@ const ( InboxDirName = "in" OutboxDirName = "out" - // TODO: Flag bit assignments do not match the revised spec. Spec defines: + // Flag bit assignments per SPEC.md: // bit 0 = has pid, bit 1 = has add to, bit 2 = common type, bit 3 = important, // bit 4 = no reply, bit 5 = deflate, bits 6-7 = reserved. - // Current implementation is missing FlagHasAddTo (bit 1) and FlagCommonType (bit 2), - // has FlagImportant on bit 1 (spec: bit 3), FlagNoReply on bit 3 (spec: bit 4), - // and defines FlagSkipChallenge (bit 4) which does not exist in the spec. - // All flag definitions and their usages must be realigned to the spec. - FlagHasPid uint8 = 1 - FlagImportant uint8 = 1 << 1 - FlagNoReply uint8 = 1 << 3 - FlagSkipChallenge uint8 = 1 << 4 - FlagDeflate uint8 = 1 << 5 + FlagHasPid uint8 = 1 + FlagHasAddTo uint8 = 1 << 1 + FlagCommonType uint8 = 1 << 2 + FlagImportant uint8 = 1 << 3 + FlagNoReply uint8 = 1 << 4 + FlagDeflate uint8 = 1 << 5 RejectCodeInvalid uint8 = 1 RejectCodeUnsupportedVersion uint8 = 2 @@ -52,19 +49,12 @@ const ( RejectCodeFutureTime uint8 = 8 RejectCodeTimeTravel uint8 = 9 RejectCodeDuplicate uint8 = 10 - // TODO: Spec defines code 11 as "accept header" (message header received for - // add-to-only messages). RejectCodeMustChallenge (11) and - // RejectCodeCannotChallenge (12) do not exist in the spec and should be - // replaced with the spec-defined code 11 = accept header. - RejectCodeMustChallenge uint8 = 11 - RejectCodeCannotChallenge uint8 = 12 - - RejectCodeUserUnknown uint8 = 100 - RejectCodeUserFull uint8 = 101 - // TODO: Add missing per-user response codes from the spec: - // 102 = user not accepting (known user but not accepting new messages) - // 103 = user undisclosed (no reason given; MAY be used instead of 100-102 - // so Host B does not have to disclose the reason). + AcceptCodeHeader uint8 = 11 + + RejectCodeUserUnknown uint8 = 100 + RejectCodeUserFull uint8 = 101 + RejectCodeUserNotAccepting uint8 = 102 + RejectCodeUserUndisclosed uint8 = 103 RejectCodeAccept uint8 = 200 ) @@ -92,14 +82,16 @@ func responseCodeName(code uint8) string { return "time travel" case RejectCodeDuplicate: return "duplicate" - case RejectCodeMustChallenge: - return "must challenge" - case RejectCodeCannotChallenge: - return "cannot challenge" + case AcceptCodeHeader: + return "accept header" case RejectCodeUserUnknown: return "user unknown" case RejectCodeUserFull: return "user full" + case RejectCodeUserNotAccepting: + return "user not accepting" + case RejectCodeUserUndisclosed: + return "user undisclosed" case RejectCodeAccept: return "accept" default: @@ -119,7 +111,6 @@ var MinDownloadRate float64 = 5000 var MinUploadRate float64 = 5000 var ReadBufferSize = 1600 var MaxMessageSize = uint32(1024 * 10) -var AllowSkipChallenge = 0 var DataDir = "got on startup" var Domain = "got on startup" var IDURI = "got on startup" @@ -136,7 +127,6 @@ func loadEnvConfig() { MinUploadRate = env.GetFloatDefault("FMSG_MIN_UPLOAD_RATE", 5000) ReadBufferSize = env.GetIntDefault("FMSG_READ_BUFFER_SIZE", 1600) MaxMessageSize = uint32(env.GetIntDefault("FMSG_MAX_MSG_SIZE", 1024*10)) - AllowSkipChallenge = env.GetIntDefault("FMSG_ALLOW_SKIP_CHALLENGE", 0) } // Updates DataDir from environment, panics if not a valid directory. @@ -505,22 +495,10 @@ func readHeader(c net.Conn) (*FMsgHeader, *bufio.Reader, error) { // at address in connection supplied by verifying the remote IP is in the // sender's _fmsg. authorised IP set. // TODO [Spec step 2]: The spec defines challenge modes (NEVER, ALWAYS, -// HAS_NOT_PARTICIPATED, DIFFERENT_DOMAIN) as implementation choices — the -// FlagSkipChallenge mechanism is not part of the spec. Refactor to use an -// implementation-defined challenge mode instead of a sender-controlled flag. +// HAS_NOT_PARTICIPATED, DIFFERENT_DOMAIN) as implementation choices. +// Currently defaults to ALWAYS. Implement configurable challenge mode. func challenge(conn net.Conn, h *FMsgHeader) error { - // skip challenge if sender requested it and we allow it - if h.Flags&FlagSkipChallenge != 0 { - if AllowSkipChallenge == 1 { - log.Printf("INFO: skip challenge requested and allowed from %s", conn.RemoteAddr().String()) - return nil - } - log.Printf("WARN: skip challenge requested but not allowed from %s", conn.RemoteAddr().String()) - rejectAccept(conn, []byte{RejectCodeMustChallenge}) - return fmt.Errorf("skip challenge requested but not allowed") - } - // verify remote IP is authorised by sender's _fmsg DNS record remoteHost, _, err := net.SplitHostPort(conn.RemoteAddr().String()) if err != nil { @@ -598,7 +576,7 @@ func validateMsgRecvForAddr(h *FMsgHeader, addr *FMsgAddress) (code uint8, err e // undisclosed). Currently RejectCodeUserUnknown (100) is returned which is // incorrect — code 100 means the address is unknown to the host. if !detail.AcceptingNew { - return RejectCodeUserUnknown, nil + return RejectCodeUserNotAccepting, nil } // check user limits From 6270f932d46cf38dd20241a823a39ce9c01e85e8 Mon Sep 17 00:00:00 2001 From: Mark Mennell Date: Wed, 1 Apr 2026 17:22:39 +0800 Subject: [PATCH 2/2] rm todo --- TODO.md | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/TODO.md b/TODO.md index 540e68a..24cc22a 100644 --- a/TODO.md +++ b/TODO.md @@ -7,17 +7,6 @@ correctness issues, then enhancements. ## P0 — Foundational (blocks most other work) -### ~~1. Realign flag bit assignments to spec~~ -**File:** `host.go` constants -~~Current flags are wrong: `FlagImportant` is on bit 1 (spec: bit 3), -`FlagNoReply` on bit 3 (spec: bit 4), and `FlagSkipChallenge` (bit 4) does not -exist in the spec. Missing: `FlagHasAddTo` (bit 1), `FlagCommonType` (bit 2). -All flag definitions and every usage site must be realigned.~~ -**DONE:** Flags realigned to spec. Added `FlagHasAddTo` (bit 1), `FlagCommonType` (bit 2). -Moved `FlagImportant` to bit 3, `FlagNoReply` to bit 4. Removed `FlagSkipChallenge`. -Removed `RejectCodeMustChallenge`/`RejectCodeCannotChallenge`, added `AcceptCodeHeader` (11), -`RejectCodeUserNotAccepting` (102), `RejectCodeUserUndisclosed` (103). -Fixed `validateMsgRecvForAddr` to return code 102 instead of 100 for non-accepting users. ### 2. Fix `Encode()` to produce the full message header per spec **File:** `defs.go` `Encode()`