Skip to content

Commit 95d985f

Browse files
author
anders-wartoft
committed
0.1.8-SNAPSHOT
1 parent 53361e8 commit 95d985f

34 files changed

Lines changed: 2417 additions & 292 deletions

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,4 @@ plan/
1313
# Build system
1414
.build-number-incremented
1515
**/pom.xml.versionsBackup
16+
src/version/version.go

BUILD_NUMBER

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
302
1+
324

Makefile

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,20 @@ include build/test.mk
1515

1616
.PHONY: all clean help
1717

18-
all: build-go build-java
18+
all: build-go-all build-java
1919
@echo "✅ All components built successfully"
2020

2121
help:
2222
@echo "Air-Gap Build System"
2323
@echo "===================="
2424
@echo ""
2525
@echo "Build Targets:"
26-
@echo " make all - Build everything (Go + Java)"
27-
@echo " make build-go - Build all Go binaries"
26+
@echo " make all - Build everything (Go all archs + Java)"
27+
@echo " make build-go - Build Go binaries (Linux AMD64)"
28+
@echo " make build-go-all - Build Go binaries (all architectures)"
29+
@echo " make build-go-linux-amd64 - Build Go binaries (Linux AMD64)"
30+
@echo " make build-go-linux-arm64 - Build Go binaries (Linux ARM64)"
31+
@echo " make build-go-mac-arm64 - Build Go binaries (macOS ARM64)"
2832
@echo " make build-java - Build Java deduplication JAR"
2933
@echo ""
3034
@echo "Package Targets:"

README.md

Lines changed: 74 additions & 108 deletions
Large diffs are not rendered by default.

Release-Notes.md

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
# Release Notes
2+
3+
## 0.1.8-SNAPSHOT
4+
5+
### Transport Layer Improvements
6+
7+
- **New TCP Transport Support**: Added TCP as an alternative to UDP for more reliable delivery over unstable networks
8+
- Configure with `transport=tcp` in upstream and downstream config files
9+
- Environment variable overrides: `AIRGAP_UPSTREAM_TRANSPORT`, `AIRGAP_DOWNSTREAM_TRANSPORT`
10+
- Automatic connection health checking with 1ms read deadline test
11+
- Automatic reconnection on connection loss
12+
- Lazy connection initialization - upstream doesn't fail on startup if downstream is unavailable
13+
- See [Transport Configuration.md](doc/Transport%20Configuration.md) for detailed TCP vs UDP comparison
14+
15+
- **Enhanced Message Delivery Reliability**:
16+
- Automatic retry logic: 30 attempts with fixed 100ms intervals (3+ seconds total) for transient failures
17+
- Messages not marked as consumed in Kafka if send fails - automatic reprocessing when receiver comes back up
18+
- Prevents message loss due to temporary network issues
19+
- Only marks Kafka message consumed on successful delivery
20+
- UDP: Transient failures log at WARN level to indicate delivery uncertainty
21+
- TCP: Automatic reconnection handling with detailed error reporting
22+
23+
- **Transport Status Monitoring**:
24+
- New `transport_status` field in periodic statistics showing transport health ("running" or error message)
25+
- Status change logging: ERROR level when status changes to error, INFO level when restored
26+
- Transport errors tracked and reported in structured statistics instead of separate log spam
27+
- Useful for monitoring and alerting on transport issues
28+
- UDP and TCP use same monitoring interface
29+
30+
### Kafka Connection Monitoring
31+
32+
- **Kafka Status Tracking**: New `kafka_status` field in statistics for both upstream and downstream
33+
- Monitors Kafka cluster availability and broker connectivity
34+
- Upstream: Custom Sarama logger captures metadata errors (leaderless partitions, connection refused, etc.)
35+
- Downstream: Kafka producer error monitoring via callback mechanism
36+
- Status changes logged at appropriate levels (ERROR for failures, INFO for recovery)
37+
- Both consumer and producer errors reported via unified callback system
38+
- Helps identify cluster issues early before message loss occurs
39+
40+
- **Error Handling Improvements**:
41+
- Kafka consumer no longer panics on connection errors - retries with 5-second backoff instead
42+
- Producer errors monitored and reported to status system
43+
- Error messages include context (attempt number, error details) for debugging
44+
- Health check goroutines with 10-second periodic validation
45+
46+
### Content-Based Filtering
47+
48+
- **New Input Filtering feature**: Content-based filtering of events at upstream before transmission
49+
- Filter events using regex patterns with allow/deny rules
50+
- Configure with `inputFilterRules`, `inputFilterDefaultAction`, `inputFilterTimeout` parameters
51+
- Environment variable overrides: `AIRGAP_UPSTREAM_INPUT_FILTER_*`
52+
- Useful for security (high-severity events only), privacy (block PII), compliance, and performance
53+
- First-match-wins rule evaluation with configurable default action (allow/deny)
54+
- Protection against ReDoS attacks with configurable regex timeout (default 100ms)
55+
- Dangerous pattern detection at startup (nested quantifiers)
56+
- New statistics counters: `filtered`, `unfiltered`, `filter_timeouts` per interval
57+
- Cumulative counters: `total_filtered`, `total_unfiltered`, `total_filter_timeouts`
58+
- See [InputFilter.md](doc/InputFilter.md) for detailed documentation and use cases
59+
60+
### Documentation
61+
62+
- Release Notes have been extracted to a separate document
63+
- A FAQ (Frequently Asked Questions) document has been created
64+
- Transport Configuration documentation added with TCP vs UDP comparison, tuning, and troubleshooting
65+
- Input Filtering documentation with examples for security, privacy, and compliance use cases
66+
- Configuration and Monitoring documentation updated with new transport and Kafka status fields
67+
68+
### Internal Improvements
69+
70+
- Protocol parser: Removed panic statements, now returns errors gracefully
71+
- Code formatting: Fixed spacing in message parsing logic
72+
- Kafka adapter: Updated to pass error callbacks for status monitoring
73+
- Configuration: Support for all environment variable overrides (AIRGAP_UPSTREAM_*, AIRGAP_DOWNSTREAM_*)
74+
- Test configurations: Added test cases 19 and 20 for input filtering and TCP testing
75+
76+
## 0.1.7-SNAPSHOT
77+
78+
- Fixed the following issues:
79+
- Support encrypted key files for communication with Kafka #5
80+
81+
## 0.1.6-SNAPSHOT
82+
83+
- Removed `topic` configuration from downstream. Downstream uses upstream's topic name, or a translation of that name.
84+
- Fixed the following issues:
85+
- resend will not accept payloadSize=auto #1
86+
- Separate internal logging from event stream from Upstream Kafka #2
87+
- Dedup can't use TLS to connect to Kafka #3
88+
89+
## 0.1.5-SNAPSHOT
90+
91+
- Multiple sockets with SO_REUSEPORT for faster and more reliable UDP receive in Linux and Mac for downstream. Fallback to single thread in Windows.
92+
- `create` application to create resend bundle files downstream
93+
- `resend` application to resend missing events from the resend bundle created by `create`
94+
- `compressWhenLengthExceeds` setting for upstream and resend to compress messages when length exceeds this value. As of now gzip is the only supported algorithm.
95+
- More configuration for upstream and downstream for buffer size optimizations
96+
- Upstream and downstream can translate topic names to other names. Useful in multi source and/or target setups.
97+
- Statistics logging in upstream, downstream and dedup
98+
99+
## 0.1.4-SNAPSHOT
100+
101+
- Changed the logging for the go applications to include log levels. Monitoring and log updates.
102+
- Changed the logging for the go applications to include log levels. Monitoring and log updates.
103+
- Documented redundancy and load balancing (see doc folder)
104+
- Documented resend (future updates will implement the new resend algorithm)
105+
106+
## 0.1.3-SNAPSHOT
107+
108+
- Added a Kafka Streams Java Application for deduplication and gap detection. Gap detection not finished.
109+
- Added upstreams filter to filter on the offset number for each partition (used in redundancy an load balancing setups)
110+
- Added a topic name mapping in downstream so a topic with a specified name upstream can be written to another topic downstream (used in redundancy an load balancing setups)
111+
- Added documentation for the new features.
112+
- Added JMX monitoring of the deduplication application. Added system monitoring documentation
113+
114+
## 0.1.2-SNAPSHOT
115+
116+
- All configuration from files can be overridden by environment variables. See Configuration Upstream
117+
- UDP sending have been made more robust
118+
- Transfer of binary data from upstream to downstream is now supported
119+
- Sending a sighup to upstream or downstream will now force a re-write of the log file, so you can rotate the log file and then sighup the application to make it log to a new file with the name specified in the upstream or downstream configuration.
120+
- air-gap now supports TLS and mTLS to Kafka upstream and downstream.
121+
- air-gap now supports TLS and mTLS to Kafka upstream and downstream.
122+
123+
## 0.1.1-SNAPSHOT
124+
125+
air-gap now supports several sending threads that all have a specified time offset, so you can start one thread that consumes everything from Kafka as soon as it's available, one that inspects Kafka content that was added for an hour ago and so on. See Automatic resend above.

build/go.mk

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# Go Binary Builds
33
# ============================================================================
44

5-
.PHONY: build-go upstream downstream create resend
5+
.PHONY: build-go build-go-all build-go-linux-amd64 build-go-linux-arm64 build-go-mac-arm64 _build-binaries upstream downstream create resend
66

77
GO_BINARIES := upstream downstream create resend
88
GO_BUILD_DIR := $(LINUX_AMD64_DIR)
@@ -12,8 +12,32 @@ GO_BUILD_DIR := $(LINUX_AMD64_DIR)
1212
@echo $(NEXT_BUILD_NUMBER) > $(BUILD_NUMBER_FILE)
1313
@touch .build-number-incremented
1414

15-
build-go: .build-number-incremented $(GO_BINARIES)
16-
@echo "✅ Go binaries built"
15+
build-go: build-go-linux-amd64
16+
@echo "✅ Go binaries built (Linux AMD64)"
17+
18+
build-go-all: build-go-linux-amd64 build-go-linux-arm64 build-go-mac-arm64
19+
@echo "✅ All Go binaries built"
20+
21+
build-go-linux-amd64: .build-number-incremented $(GO_BINARIES)
22+
@echo "✅ Go binaries built (Linux AMD64)"
23+
24+
build-go-linux-arm64: .build-number-incremented src/version/version.go
25+
@echo "Building binaries (linux arm64)..."
26+
@mkdir -p $(LINUX_ARM64_DIR)
27+
@GOOS=linux GOARCH=arm64 go build -ldflags '$(BUILD_LDFLAGS)' -o $(LINUX_ARM64_DIR)/upstream ./src/cmd/upstream
28+
@GOOS=linux GOARCH=arm64 go build -ldflags '$(BUILD_LDFLAGS)' -o $(LINUX_ARM64_DIR)/downstream ./src/cmd/downstream
29+
@GOOS=linux GOARCH=arm64 go build -ldflags '$(BUILD_LDFLAGS)' -o $(LINUX_ARM64_DIR)/create ./src/cmd/create
30+
@GOOS=linux GOARCH=arm64 go build -ldflags '$(BUILD_LDFLAGS)' -o $(LINUX_ARM64_DIR)/resend ./src/cmd/resend
31+
@echo "✅ Go binaries built (Linux ARM64)"
32+
33+
build-go-mac-arm64: .build-number-incremented src/version/version.go
34+
@echo "Building binaries (darwin arm64)..."
35+
@mkdir -p $(MAC_ARM64_DIR)
36+
@GOOS=darwin GOARCH=arm64 go build -ldflags '$(BUILD_LDFLAGS)' -o $(MAC_ARM64_DIR)/upstream ./src/cmd/upstream
37+
@GOOS=darwin GOARCH=arm64 go build -ldflags '$(BUILD_LDFLAGS)' -o $(MAC_ARM64_DIR)/downstream ./src/cmd/downstream
38+
@GOOS=darwin GOARCH=arm64 go build -ldflags '$(BUILD_LDFLAGS)' -o $(MAC_ARM64_DIR)/create ./src/cmd/create
39+
@GOOS=darwin GOARCH=arm64 go build -ldflags '$(BUILD_LDFLAGS)' -o $(MAC_ARM64_DIR)/resend ./src/cmd/resend
40+
@echo "✅ Go binaries built (macOS ARM64)"
1741

1842
# Generate version file
1943
src/version/version.go:

build/variables.mk

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ TARGET_DIR := target
2020
DIST_DIR := $(TARGET_DIR)/dist
2121
LINUX_AMD64_DIR := $(TARGET_DIR)/linux-amd64
2222
LINUX_ARM64_DIR := $(TARGET_DIR)/linux-arm64
23+
MAC_ARM64_DIR := $(TARGET_DIR)/darwin-arm64
2324
JAVA_TARGET_DIR := java-streams/target
2425

2526
# nfpm Configuration
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
id=test-tcp-downstream
2+
nic=lo
3+
targetIP=127.0.0.1
4+
targetPort=9999
5+
bootstrapServers=localhost:9092
6+
topic=airgap-internal
7+
target=null
8+
transport=tcp
9+
logLevel=DEBUG
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Used in some log events to identify the source
2+
id=Downstream_19
3+
# Used in the MTU code
4+
nic=lo0
5+
# UDP address to listen on
6+
targetIP=0.0.0.0
7+
# UDP port to listen on
8+
targetPort=1234
9+
# Kafka target. If more than one, separate the servers with a comma ,
10+
bootstrapServers=kafka-downstream.sitia.nu:9092
11+
# Topic to write internal logging to
12+
internalTopic=airgap-internal
13+
14+
# kafka or cmd
15+
target=kafka
16+
17+
# More logging
18+
logLevel=debug
19+
20+
# Client id to use when sending events to Kafka. Will be overridden by the certificate CN if Kafka mTLS is used
21+
clientId=downstream-19
22+
23+
# Glob that will identify the path(s) to all private keys we should try to use
24+
# when a key exchange packet is received
25+
privateKeyFiles=certs/private*.pem
26+
27+
#mtu=auto
28+
mtu=1500
29+
# After reading the config, where should we send the logs? Default is stdout
30+
#logFileName=./tmp/downstream.log
31+
32+
# TLS to Kafka
33+
# Certificate file
34+
#certFile=certs/tmp/airgap-downstream.crt
35+
# Key file
36+
#keyFile=certs/tmp/airgap-downstream.key
37+
# CA file
38+
#caFile=certs/tmp/kafka-ca.crt
39+
40+
# This is the magic that saves the upstream topic 'transfer' to the downstream topic 'transfer-12b'
41+
#topicTranslations={"transfer": "transfer-13"}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# Used in some log events to identify the source
2+
id=Downstream_20
3+
# Used in the MTU code
4+
nic=lo0
5+
# UDP address to listen on
6+
targetIP=0.0.0.0
7+
# UDP port to listen on
8+
targetPort=1234
9+
# Kafka target. If more than one, separate the servers with a comma ,
10+
bootstrapServers=kafka-downstream.sitia.nu:9092
11+
# Topic to write internal logging to
12+
internalTopic=airgap-internal
13+
14+
# kafka or cmd
15+
target=kafka
16+
17+
# More logging
18+
logLevel=debug
19+
20+
# Client id to use when sending events to Kafka. Will be overridden by the certificate CN if Kafka mTLS is used
21+
clientId=downstream-20
22+
23+
# Glob that will identify the path(s) to all private keys we should try to use
24+
# when a key exchange packet is received
25+
privateKeyFiles=certs/private*.pem
26+
27+
#mtu=auto
28+
mtu=1500
29+
# After reading the config, where should we send the logs? Default is stdout
30+
#logFileName=./tmp/downstream.log
31+
32+
transport=tcp
33+
34+
# TLS to Kafka
35+
# Certificate file
36+
#certFile=certs/tmp/airgap-downstream.crt
37+
# Key file
38+
#keyFile=certs/tmp/airgap-downstream.key
39+
# CA file
40+
#caFile=certs/tmp/kafka-ca.crt
41+
42+
# This is the magic that saves the upstream topic 'transfer' to the downstream topic 'transfer-12b'
43+
#topicTranslations={"transfer": "transfer-13"}

0 commit comments

Comments
 (0)