@mytechtoday/augment-extensions 1.4.0 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/augment-extensions/coding-standards/c/CHANGELOG.md +55 -0
- package/augment-extensions/coding-standards/c/LICENSE +22 -0
- package/augment-extensions/coding-standards/c/README.md +167 -0
- package/augment-extensions/coding-standards/c/config/defaults.json +26 -0
- package/augment-extensions/coding-standards/c/config/examples/embedded.yaml +25 -0
- package/augment-extensions/coding-standards/c/config/examples/systems.json +31 -0
- package/augment-extensions/coding-standards/c/config/schema.json +244 -0
- package/augment-extensions/coding-standards/c/docs/API.md +613 -0
- package/augment-extensions/coding-standards/c/docs/CONFIGURATION.md +259 -0
- package/augment-extensions/coding-standards/c/docs/USER_GUIDE.md +567 -0
- package/augment-extensions/coding-standards/c/examples/drivers/Makefile +33 -0
- package/augment-extensions/coding-standards/c/examples/drivers/README.md +192 -0
- package/augment-extensions/coding-standards/c/examples/drivers/dma-example.c +224 -0
- package/augment-extensions/coding-standards/c/examples/drivers/example.dts +64 -0
- package/augment-extensions/coding-standards/c/examples/drivers/platform-driver.c +174 -0
- package/augment-extensions/coding-standards/c/examples/embedded/README.md +167 -0
- package/augment-extensions/coding-standards/c/examples/embedded/gpio-control.c +172 -0
- package/augment-extensions/coding-standards/c/examples/embedded/timer-isr.c +198 -0
- package/augment-extensions/coding-standards/c/examples/embedded/uart-communication.c +212 -0
- package/augment-extensions/coding-standards/c/examples/kernel/Makefile +82 -0
- package/augment-extensions/coding-standards/c/examples/kernel/README.md +168 -0
- package/augment-extensions/coding-standards/c/examples/kernel/char-device.c +198 -0
- package/augment-extensions/coding-standards/c/examples/kernel/proc-file.c +131 -0
- package/augment-extensions/coding-standards/c/examples/kernel/simple-module.c +111 -0
- package/augment-extensions/coding-standards/c/examples/legacy/Makefile +62 -0
- package/augment-extensions/coding-standards/c/examples/legacy/README.md +255 -0
- package/augment-extensions/coding-standards/c/examples/legacy/c89-to-c11-migration.c +268 -0
- package/augment-extensions/coding-standards/c/examples/legacy/compatibility-layer.c +239 -0
- package/augment-extensions/coding-standards/c/examples/networking/Makefile +35 -0
- package/augment-extensions/coding-standards/c/examples/networking/README.md +207 -0
- package/augment-extensions/coding-standards/c/examples/networking/protocol-parser.c +270 -0
- package/augment-extensions/coding-standards/c/examples/networking/tcp-server.c +197 -0
- package/augment-extensions/coding-standards/c/examples/networking/udp-multicast.c +220 -0
- package/augment-extensions/coding-standards/c/examples/realtime/Makefile +53 -0
- package/augment-extensions/coding-standards/c/examples/realtime/README.md +199 -0
- package/augment-extensions/coding-standards/c/examples/realtime/deadline-monitoring.c +260 -0
- package/augment-extensions/coding-standards/c/examples/realtime/priority-scheduling.c +258 -0
- package/augment-extensions/coding-standards/c/examples/systems/Makefile +34 -0
- package/augment-extensions/coding-standards/c/examples/systems/README.md +123 -0
- package/augment-extensions/coding-standards/c/examples/systems/ipc-pipes.c +181 -0
- package/augment-extensions/coding-standards/c/examples/systems/process-management.c +153 -0
- package/augment-extensions/coding-standards/c/examples/systems/signal-handling.c +162 -0
- package/augment-extensions/coding-standards/c/module.json +149 -0
- package/augment-extensions/coding-standards/c/rules/categories/drivers.md +635 -0
- package/augment-extensions/coding-standards/c/rules/categories/embedded.md +510 -0
- package/augment-extensions/coding-standards/c/rules/categories/kernel.md +653 -0
- package/augment-extensions/coding-standards/c/rules/categories/legacy.md +526 -0
- package/augment-extensions/coding-standards/c/rules/categories/networking.md +735 -0
- package/augment-extensions/coding-standards/c/rules/categories/realtime.md +631 -0
- package/augment-extensions/coding-standards/c/rules/categories/systems.md +586 -0
- package/augment-extensions/coding-standards/c/rules/universal/const-correctness.md +275 -0
- package/augment-extensions/coding-standards/c/rules/universal/documentation.md +251 -0
- package/augment-extensions/coding-standards/c/rules/universal/error-handling.md +250 -0
- package/augment-extensions/coding-standards/c/rules/universal/header-guards.md +254 -0
- package/augment-extensions/coding-standards/c/rules/universal/memory-safety.md +233 -0
- package/augment-extensions/coding-standards/c/rules/universal/naming.md +146 -0
- package/augment-extensions/coding-standards/c/src/conflict-detector.ts +461 -0
- package/augment-extensions/coding-standards/c/src/prompt-generator.ts +307 -0
- package/augment-extensions/coding-standards/c/src/rule-evaluator.ts +307 -0
- package/augment-extensions/coding-standards/c/src/rule-override.ts +427 -0
- package/augment-extensions/coding-standards/c/src/template-engine.ts +217 -0
- package/augment-extensions/coding-standards/c/templates/prompts/drivers.txt +191 -0
- package/augment-extensions/coding-standards/c/templates/prompts/embedded.txt +164 -0
- package/augment-extensions/coding-standards/c/templates/prompts/kernel.txt +175 -0
- package/augment-extensions/coding-standards/c/templates/prompts/legacy.txt +280 -0
- package/augment-extensions/coding-standards/c/templates/prompts/networking.txt +259 -0
- package/augment-extensions/coding-standards/c/templates/prompts/realtime.txt +219 -0
- package/augment-extensions/coding-standards/c/templates/prompts/systems.txt +147 -0
- package/augment-extensions/coding-standards/c/tests/integration/category-specific.test.ts +356 -0
- package/augment-extensions/coding-standards/c/tests/integration/end-to-end-workflow.test.ts +377 -0
- package/augment-extensions/coding-standards/c/tests/performance/benchmarks.test.ts +407 -0
- package/augment-extensions/coding-standards/c/tests/unit/config-manager.test.ts +345 -0
- package/augment-extensions/coding-standards/c/tests/unit/conflict-detector.test.ts +294 -0
- package/augment-extensions/coding-standards/c/tests/unit/prompt-generator.test.ts +174 -0
- package/augment-extensions/coding-standards/c/tests/unit/registry.test.ts +313 -0
- package/augment-extensions/coding-standards/c/tests/unit/rule-evaluator.test.ts +318 -0
- package/augment-extensions/coding-standards/c/tests/unit/rule-override.test.ts +326 -0
- package/augment-extensions/coding-standards/c/tests/unit/template-engine.test.ts +314 -0
- package/augment-extensions/coding-standards/go/CHARACTER-COUNT-REPORT.md +135 -0
- package/augment-extensions/coding-standards/go/PHASE1-COMPLETION.md +146 -0
- package/augment-extensions/coding-standards/go/PHASE4-COMPLETION.md +184 -0
- package/augment-extensions/coding-standards/go/README.md +200 -0
- package/augment-extensions/coding-standards/go/VALIDATION-CHECKLIST.md +154 -0
- package/augment-extensions/coding-standards/go/config/examples/example-cli.json +15 -0
- package/augment-extensions/coding-standards/go/config/examples/example-microservices.json +21 -0
- package/augment-extensions/coding-standards/go/config/examples/example-multi-category.yaml +24 -0
- package/augment-extensions/coding-standards/go/config/examples/example-web.json +15 -0
- package/augment-extensions/coding-standards/go/config/schema.json +110 -0
- package/augment-extensions/coding-standards/go/docs/CATEGORIES.md +221 -0
- package/augment-extensions/coding-standards/go/docs/CONFIGURATION.md +198 -0
- package/augment-extensions/coding-standards/go/docs/TROUBLESHOOTING.md +285 -0
- package/augment-extensions/coding-standards/go/examples/cli/cobra-app.go +287 -0
- package/augment-extensions/coding-standards/go/examples/cloud-native-app.go +217 -0
- package/augment-extensions/coding-standards/go/examples/devops-tool.go +250 -0
- package/augment-extensions/coding-standards/go/examples/distributed-system.go +247 -0
- package/augment-extensions/coding-standards/go/examples/microservices/grpc-service.go +253 -0
- package/augment-extensions/coding-standards/go/examples/rest-api.go +270 -0
- package/augment-extensions/coding-standards/go/examples/web/http-server.go +224 -0
- package/augment-extensions/coding-standards/go/module.json +139 -0
- package/augment-extensions/coding-standards/go/rules/categories/api-development/api-versioning.md +149 -0
- package/augment-extensions/coding-standards/go/rules/categories/api-development/rate-limiting.md +209 -0
- package/augment-extensions/coding-standards/go/rules/categories/api-development/rest-api-design.md +183 -0
- package/augment-extensions/coding-standards/go/rules/categories/cloud-native/cloud-config.md +193 -0
- package/augment-extensions/coding-standards/go/rules/categories/cloud-native/health-checks.md +231 -0
- package/augment-extensions/coding-standards/go/rules/categories/cloud-native/kubernetes.md +180 -0
- package/augment-extensions/coding-standards/go/rules/categories/devops-tooling/automation.md +179 -0
- package/augment-extensions/coding-standards/go/rules/categories/devops-tooling/ci-cd-integration.md +147 -0
- package/augment-extensions/coding-standards/go/rules/categories/devops-tooling/infrastructure-as-code.md +231 -0
- package/augment-extensions/coding-standards/go/rules/categories/distributed-systems/caching.md +150 -0
- package/augment-extensions/coding-standards/go/rules/categories/distributed-systems/consensus.md +187 -0
- package/augment-extensions/coding-standards/go/rules/categories/distributed-systems/event-sourcing.md +246 -0
- package/augment-extensions/coding-standards/go/rules/cli/command-parsing.md +264 -0
- package/augment-extensions/coding-standards/go/rules/cli/configuration.md +268 -0
- package/augment-extensions/coding-standards/go/rules/cli/cross-platform.md +324 -0
- package/augment-extensions/coding-standards/go/rules/microservices/distributed-tracing.md +253 -0
- package/augment-extensions/coding-standards/go/rules/microservices/grpc.md +257 -0
- package/augment-extensions/coding-standards/go/rules/microservices/metrics.md +278 -0
- package/augment-extensions/coding-standards/go/rules/microservices/service-discovery.md +249 -0
- package/augment-extensions/coding-standards/go/rules/universal/code-organization.md +221 -0
- package/augment-extensions/coding-standards/go/rules/universal/documentation.md +269 -0
- package/augment-extensions/coding-standards/go/rules/universal/performance.md +323 -0
- package/augment-extensions/coding-standards/go/rules/universal/testing.md +162 -0
- package/augment-extensions/coding-standards/go/rules/web/graceful-shutdown.md +249 -0
- package/augment-extensions/coding-standards/go/rules/web/http-handlers.md +164 -0
- package/augment-extensions/coding-standards/go/rules/web/middleware.md +234 -0
- package/augment-extensions/coding-standards/go/rules/web/routing.md +251 -0
- package/augment-extensions/coding-standards/go/templates/prompts/api.md +160 -0
- package/augment-extensions/coding-standards/go/templates/prompts/cli.md +225 -0
- package/augment-extensions/coding-standards/go/templates/prompts/cloud-native.md +121 -0
- package/augment-extensions/coding-standards/go/templates/prompts/devops.md +146 -0
- package/augment-extensions/coding-standards/go/templates/prompts/distributed.md +133 -0
- package/augment-extensions/coding-standards/go/templates/prompts/microservices.md +225 -0
- package/augment-extensions/coding-standards/go/templates/prompts/web.md +181 -0
- package/augment-extensions/coding-standards/go/tests/integration/module-integration.test.ts +164 -0
- package/augment-extensions/coding-standards/go/tests/unit/category-selection.test.ts +147 -0
- package/augment-extensions/coding-standards/go/tests/unit/module-structure.test.ts +154 -0
- package/augment-extensions/coding-standards/go/tests/validate-character-count.ps1 +13 -0
- package/augment-extensions/coding-standards/go/tests/validate-examples.ps1 +148 -0
- package/augment-extensions/coding-standards/go/tests/validate-examples.sh +135 -0
- package/cli/dist/analysis/ast-parser.d.ts +47 -0
- package/cli/dist/analysis/ast-parser.d.ts.map +1 -0
- package/cli/dist/analysis/ast-parser.js +161 -0
- package/cli/dist/analysis/ast-parser.js.map +1 -0
- package/cli/dist/analysis/complexity-analyzer.d.ts +27 -0
- package/cli/dist/analysis/complexity-analyzer.d.ts.map +1 -0
- package/cli/dist/analysis/complexity-analyzer.js +189 -0
- package/cli/dist/analysis/complexity-analyzer.js.map +1 -0
- package/cli/dist/analysis/dependency-analyzer.d.ts +23 -0
- package/cli/dist/analysis/dependency-analyzer.d.ts.map +1 -0
- package/cli/dist/analysis/dependency-analyzer.js +237 -0
- package/cli/dist/analysis/dependency-analyzer.js.map +1 -0
- package/cli/dist/analysis/index.d.ts +9 -0
- package/cli/dist/analysis/index.d.ts.map +1 -0
- package/cli/dist/analysis/index.js +25 -0
- package/cli/dist/analysis/index.js.map +1 -0
- package/cli/dist/analysis/security-scanner.d.ts +11 -0
- package/cli/dist/analysis/security-scanner.d.ts.map +1 -0
- package/cli/dist/analysis/security-scanner.js +294 -0
- package/cli/dist/analysis/security-scanner.js.map +1 -0
- package/cli/dist/analysis/types.d.ts +151 -0
- package/cli/dist/analysis/types.d.ts.map +1 -0
- package/cli/dist/analysis/types.js +6 -0
- package/cli/dist/analysis/types.js.map +1 -0
- package/cli/dist/cli.js +24 -0
- package/cli/dist/cli.js.map +1 -1
- package/cli/dist/commands/code-analysis.d.ts +11 -0
- package/cli/dist/commands/code-analysis.d.ts.map +1 -0
- package/cli/dist/commands/code-analysis.js +412 -0
- package/cli/dist/commands/code-analysis.js.map +1 -0
- package/modules.md +99 -3
- package/package.json +14 -2
- package/cli/dist/commands/agent.d.ts +0 -37
- package/cli/dist/commands/agent.d.ts.map +0 -1
- package/cli/dist/commands/agent.js +0 -222
- package/cli/dist/commands/agent.js.map +0 -1
- package/cli/dist/commands/beads.d.ts +0 -64
- package/cli/dist/commands/beads.d.ts.map +0 -1
- package/cli/dist/commands/beads.js +0 -377
- package/cli/dist/commands/beads.js.map +0 -1
- package/cli/dist/commands/change.d.ts +0 -54
- package/cli/dist/commands/change.d.ts.map +0 -1
- package/cli/dist/commands/change.js +0 -243
- package/cli/dist/commands/change.js.map +0 -1
- package/cli/dist/commands/clean.d.ts +0 -15
- package/cli/dist/commands/clean.d.ts.map +0 -1
- package/cli/dist/commands/clean.js +0 -63
- package/cli/dist/commands/clean.js.map +0 -1
- package/cli/dist/commands/clone.d.ts +0 -15
- package/cli/dist/commands/clone.d.ts.map +0 -1
- package/cli/dist/commands/clone.js +0 -49
- package/cli/dist/commands/clone.js.map +0 -1
- package/cli/dist/commands/config.d.ts +0 -33
- package/cli/dist/commands/config.d.ts.map +0 -1
- package/cli/dist/commands/config.js +0 -166
- package/cli/dist/commands/config.js.map +0 -1
- package/cli/dist/commands/context.d.ts +0 -38
- package/cli/dist/commands/context.d.ts.map +0 -1
- package/cli/dist/commands/context.js +0 -205
- package/cli/dist/commands/context.js.map +0 -1
- package/cli/dist/commands/create.d.ts +0 -18
- package/cli/dist/commands/create.d.ts.map +0 -1
- package/cli/dist/commands/create.js +0 -178
- package/cli/dist/commands/create.js.map +0 -1
- package/cli/dist/commands/diff.d.ts +0 -19
- package/cli/dist/commands/diff.d.ts.map +0 -1
- package/cli/dist/commands/diff.js +0 -104
- package/cli/dist/commands/diff.js.map +0 -1
- package/cli/dist/commands/doctor.d.ts +0 -14
- package/cli/dist/commands/doctor.d.ts.map +0 -1
- package/cli/dist/commands/doctor.js +0 -62
- package/cli/dist/commands/doctor.js.map +0 -1
- package/cli/dist/commands/export.d.ts +0 -28
- package/cli/dist/commands/export.d.ts.map +0 -1
- package/cli/dist/commands/export.js +0 -135
- package/cli/dist/commands/export.js.map +0 -1
- package/cli/dist/commands/import.d.ts +0 -23
- package/cli/dist/commands/import.d.ts.map +0 -1
- package/cli/dist/commands/import.js +0 -118
- package/cli/dist/commands/import.js.map +0 -1
- package/cli/dist/commands/prompt.d.ts +0 -45
- package/cli/dist/commands/prompt.d.ts.map +0 -1
- package/cli/dist/commands/prompt.js +0 -223
- package/cli/dist/commands/prompt.js.map +0 -1
- package/cli/dist/commands/spec.d.ts +0 -57
- package/cli/dist/commands/spec.d.ts.map +0 -1
- package/cli/dist/commands/spec.js +0 -279
- package/cli/dist/commands/spec.js.map +0 -1
- package/cli/dist/commands/stats.d.ts +0 -18
- package/cli/dist/commands/stats.d.ts.map +0 -1
- package/cli/dist/commands/stats.js +0 -85
- package/cli/dist/commands/stats.js.map +0 -1
- package/cli/dist/commands/task.d.ts +0 -65
- package/cli/dist/commands/task.d.ts.map +0 -1
- package/cli/dist/commands/task.js +0 -282
- package/cli/dist/commands/task.js.map +0 -1
- package/cli/dist/commands/template.d.ts +0 -17
- package/cli/dist/commands/template.d.ts.map +0 -1
- package/cli/dist/commands/template.js +0 -55
- package/cli/dist/commands/template.js.map +0 -1
- package/cli/dist/utils/agent-config.d.ts +0 -129
- package/cli/dist/utils/agent-config.d.ts.map +0 -1
- package/cli/dist/utils/agent-config.js +0 -297
- package/cli/dist/utils/agent-config.js.map +0 -1
- package/cli/dist/utils/beads-graph.d.ts +0 -17
- package/cli/dist/utils/beads-graph.d.ts.map +0 -1
- package/cli/dist/utils/beads-graph.js +0 -150
- package/cli/dist/utils/beads-graph.js.map +0 -1
- package/cli/dist/utils/beads-integration.d.ts +0 -112
- package/cli/dist/utils/beads-integration.d.ts.map +0 -1
- package/cli/dist/utils/beads-integration.js +0 -312
- package/cli/dist/utils/beads-integration.js.map +0 -1
- package/cli/dist/utils/beads-reporter.d.ts +0 -17
- package/cli/dist/utils/beads-reporter.d.ts.map +0 -1
- package/cli/dist/utils/beads-reporter.js +0 -160
- package/cli/dist/utils/beads-reporter.js.map +0 -1
- package/cli/dist/utils/cache-manager.d.ts +0 -55
- package/cli/dist/utils/cache-manager.d.ts.map +0 -1
- package/cli/dist/utils/cache-manager.js +0 -150
- package/cli/dist/utils/cache-manager.js.map +0 -1
- package/cli/dist/utils/change-manager.d.ts +0 -70
- package/cli/dist/utils/change-manager.d.ts.map +0 -1
- package/cli/dist/utils/change-manager.js +0 -412
- package/cli/dist/utils/change-manager.js.map +0 -1
- package/cli/dist/utils/config-manager-enhanced.d.ts +0 -66
- package/cli/dist/utils/config-manager-enhanced.d.ts.map +0 -1
- package/cli/dist/utils/config-manager-enhanced.js +0 -77
- package/cli/dist/utils/config-manager-enhanced.js.map +0 -1
- package/cli/dist/utils/context-manager.d.ts +0 -96
- package/cli/dist/utils/context-manager.d.ts.map +0 -1
- package/cli/dist/utils/context-manager.js +0 -258
- package/cli/dist/utils/context-manager.js.map +0 -1
- package/cli/dist/utils/diff-engine.d.ts +0 -78
- package/cli/dist/utils/diff-engine.d.ts.map +0 -1
- package/cli/dist/utils/diff-engine.js +0 -233
- package/cli/dist/utils/diff-engine.js.map +0 -1
- package/cli/dist/utils/export-system.d.ts +0 -101
- package/cli/dist/utils/export-system.d.ts.map +0 -1
- package/cli/dist/utils/export-system.js +0 -289
- package/cli/dist/utils/export-system.js.map +0 -1
- package/cli/dist/utils/health-checker.d.ts +0 -66
- package/cli/dist/utils/health-checker.d.ts.map +0 -1
- package/cli/dist/utils/health-checker.js +0 -285
- package/cli/dist/utils/health-checker.js.map +0 -1
- package/cli/dist/utils/import-system.d.ts +0 -74
- package/cli/dist/utils/import-system.d.ts.map +0 -1
- package/cli/dist/utils/import-system.js +0 -317
- package/cli/dist/utils/import-system.js.map +0 -1
- package/cli/dist/utils/module-cloner.d.ts +0 -40
- package/cli/dist/utils/module-cloner.d.ts.map +0 -1
- package/cli/dist/utils/module-cloner.js +0 -136
- package/cli/dist/utils/module-cloner.js.map +0 -1
- package/cli/dist/utils/prompt-manager.d.ts +0 -90
- package/cli/dist/utils/prompt-manager.d.ts.map +0 -1
- package/cli/dist/utils/prompt-manager.js +0 -302
- package/cli/dist/utils/prompt-manager.js.map +0 -1
- package/cli/dist/utils/spec-manager.d.ts +0 -65
- package/cli/dist/utils/spec-manager.d.ts.map +0 -1
- package/cli/dist/utils/spec-manager.js +0 -329
- package/cli/dist/utils/spec-manager.js.map +0 -1
- package/cli/dist/utils/stats-collector.d.ts +0 -74
- package/cli/dist/utils/stats-collector.d.ts.map +0 -1
- package/cli/dist/utils/stats-collector.js +0 -164
- package/cli/dist/utils/stats-collector.js.map +0 -1
- package/cli/dist/utils/template-engine.d.ts +0 -47
- package/cli/dist/utils/template-engine.d.ts.map +0 -1
- package/cli/dist/utils/template-engine.js +0 -204
- package/cli/dist/utils/template-engine.js.map +0 -1
|
@@ -0,0 +1,735 @@
|
|
|
1
|
+
# Rule: Networking
|
|
2
|
+
|
|
3
|
+
## Metadata
|
|
4
|
+
- **ID**: category-networking
|
|
5
|
+
- **Category**: networking
|
|
6
|
+
- **Severity**: ERROR
|
|
7
|
+
- **Standard**: POSIX Sockets, RFC Standards
|
|
8
|
+
- **Version**: 1.0.0
|
|
9
|
+
|
|
10
|
+
## Description
|
|
11
|
+
Networking programming rules for socket programming, protocol implementation, packet handling, byte order conversion, and non-blocking I/O.
|
|
12
|
+
|
|
13
|
+
## Rationale
|
|
14
|
+
Network programming requires careful handling of byte order, partial reads/writes, connection states, and error conditions. Improper network code can lead to data corruption, security vulnerabilities, and resource leaks.
|
|
15
|
+
|
|
16
|
+
## Applies To
|
|
17
|
+
- C Standards: c99, c11, c17, c23
|
|
18
|
+
- Categories: networking
|
|
19
|
+
- Platforms: POSIX-compliant systems, embedded networking stacks
|
|
20
|
+
|
|
21
|
+
## Rule Details
|
|
22
|
+
|
|
23
|
+
### 1. Socket Programming
|
|
24
|
+
- Always check socket() return value
|
|
25
|
+
- Use appropriate socket types (SOCK_STREAM, SOCK_DGRAM)
|
|
26
|
+
- Set socket options correctly
|
|
27
|
+
- Close sockets properly
|
|
28
|
+
- Handle connection failures
|
|
29
|
+
|
|
30
|
+
### 2. Byte Order Conversion
|
|
31
|
+
- Use htons/htonl for host-to-network
|
|
32
|
+
- Use ntohs/ntohl for network-to-host
|
|
33
|
+
- Convert all multi-byte values
|
|
34
|
+
- Document byte order assumptions
|
|
35
|
+
|
|
36
|
+
### 3. Partial Reads/Writes
|
|
37
|
+
- Handle partial send/recv
|
|
38
|
+
- Loop until all data transferred
|
|
39
|
+
- Check for EINTR and retry
|
|
40
|
+
- Use MSG_WAITALL when appropriate
|
|
41
|
+
|
|
42
|
+
### 4. Non-Blocking I/O
|
|
43
|
+
- Use select/poll/epoll for multiplexing
|
|
44
|
+
- Handle EAGAIN/EWOULDBLOCK
|
|
45
|
+
- Set O_NONBLOCK flag correctly
|
|
46
|
+
- Implement proper timeout handling
|
|
47
|
+
|
|
48
|
+
### 5. Protocol Implementation
|
|
49
|
+
- Follow RFC specifications
|
|
50
|
+
- Validate all input data
|
|
51
|
+
- Implement proper state machines
|
|
52
|
+
- Handle protocol errors gracefully
|
|
53
|
+
|
|
54
|
+
## Examples
|
|
55
|
+
|
|
56
|
+
### ✅ Example 1: TCP Server Socket Setup
|
|
57
|
+
|
|
58
|
+
```c
|
|
59
|
+
#include <sys/socket.h>
|
|
60
|
+
#include <netinet/in.h>
|
|
61
|
+
#include <arpa/inet.h>
|
|
62
|
+
#include <unistd.h>
|
|
63
|
+
#include <string.h>
|
|
64
|
+
#include <errno.h>
|
|
65
|
+
#include <stdio.h>
|
|
66
|
+
|
|
67
|
+
int create_tcp_server(uint16_t port) {
|
|
68
|
+
int sockfd;
|
|
69
|
+
struct sockaddr_in server_addr;
|
|
70
|
+
int opt = 1;
|
|
71
|
+
|
|
72
|
+
// Create socket
|
|
73
|
+
sockfd = socket(AF_INET, SOCK_STREAM, 0);
|
|
74
|
+
if (sockfd < 0) {
|
|
75
|
+
perror("socket");
|
|
76
|
+
return -1;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Set socket options (reuse address)
|
|
80
|
+
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) {
|
|
81
|
+
perror("setsockopt");
|
|
82
|
+
close(sockfd);
|
|
83
|
+
return -1;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Bind to address
|
|
87
|
+
memset(&server_addr, 0, sizeof(server_addr));
|
|
88
|
+
server_addr.sin_family = AF_INET;
|
|
89
|
+
server_addr.sin_addr.s_addr = INADDR_ANY;
|
|
90
|
+
server_addr.sin_port = htons(port); // Host to network byte order
|
|
91
|
+
|
|
92
|
+
if (bind(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) {
|
|
93
|
+
perror("bind");
|
|
94
|
+
close(sockfd);
|
|
95
|
+
return -1;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Listen for connections
|
|
99
|
+
if (listen(sockfd, 5) < 0) {
|
|
100
|
+
perror("listen");
|
|
101
|
+
close(sockfd);
|
|
102
|
+
return -1;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
return sockfd;
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### ❌ Example 1: Poor Socket Setup
|
|
110
|
+
|
|
111
|
+
```c
|
|
112
|
+
// WRONG: No error checking, missing byte order conversion
|
|
113
|
+
int bad_server(uint16_t port) {
|
|
114
|
+
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
|
|
115
|
+
struct sockaddr_in addr;
|
|
116
|
+
addr.sin_port = port; // WRONG: Missing htons()!
|
|
117
|
+
bind(sockfd, (struct sockaddr*)&addr, sizeof(addr));
|
|
118
|
+
listen(sockfd, 5);
|
|
119
|
+
return sockfd; // No error checking!
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### ✅ Example 2: Handling Partial Reads/Writes
|
|
124
|
+
|
|
125
|
+
```c
|
|
126
|
+
#include <sys/socket.h>
|
|
127
|
+
#include <errno.h>
|
|
128
|
+
|
|
129
|
+
// Send all data, handling partial writes
|
|
130
|
+
ssize_t send_all(int sockfd, const void *buf, size_t len) {
|
|
131
|
+
size_t total_sent = 0;
|
|
132
|
+
ssize_t n;
|
|
133
|
+
|
|
134
|
+
while (total_sent < len) {
|
|
135
|
+
n = send(sockfd, (char*)buf + total_sent, len - total_sent, 0);
|
|
136
|
+
|
|
137
|
+
if (n < 0) {
|
|
138
|
+
if (errno == EINTR) {
|
|
139
|
+
continue; // Interrupted, retry
|
|
140
|
+
}
|
|
141
|
+
return -1; // Error
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
if (n == 0) {
|
|
145
|
+
break; // Connection closed
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
total_sent += n;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
return total_sent;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// Receive all data, handling partial reads
|
|
155
|
+
ssize_t recv_all(int sockfd, void *buf, size_t len) {
|
|
156
|
+
size_t total_received = 0;
|
|
157
|
+
ssize_t n;
|
|
158
|
+
|
|
159
|
+
while (total_received < len) {
|
|
160
|
+
n = recv(sockfd, (char*)buf + total_received, len - total_received, 0);
|
|
161
|
+
|
|
162
|
+
if (n < 0) {
|
|
163
|
+
if (errno == EINTR) {
|
|
164
|
+
continue; // Interrupted, retry
|
|
165
|
+
}
|
|
166
|
+
return -1; // Error
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
if (n == 0) {
|
|
170
|
+
break; // Connection closed
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
total_received += n;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
return total_received;
|
|
177
|
+
}
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### ❌ Example 2: Ignoring Partial Transfers
|
|
181
|
+
|
|
182
|
+
```c
|
|
183
|
+
// WRONG: Assumes send/recv transfer all data
|
|
184
|
+
void bad_transfer(int sockfd, char *buf, size_t len) {
|
|
185
|
+
send(sockfd, buf, len, 0); // May send less than len!
|
|
186
|
+
recv(sockfd, buf, len, 0); // May receive less than len!
|
|
187
|
+
}
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### ✅ Example 3: Byte Order Conversion
|
|
191
|
+
|
|
192
|
+
```c
|
|
193
|
+
#include <stdint.h>
|
|
194
|
+
#include <arpa/inet.h>
|
|
195
|
+
|
|
196
|
+
// Network protocol header
|
|
197
|
+
typedef struct {
|
|
198
|
+
uint16_t message_type;
|
|
199
|
+
uint16_t message_length;
|
|
200
|
+
uint32_t sequence_number;
|
|
201
|
+
uint32_t timestamp;
|
|
202
|
+
} __attribute__((packed)) MessageHeader;
|
|
203
|
+
|
|
204
|
+
// Serialize header to network byte order
|
|
205
|
+
void serialize_header(MessageHeader *hdr) {
|
|
206
|
+
hdr->message_type = htons(hdr->message_type);
|
|
207
|
+
hdr->message_length = htons(hdr->message_length);
|
|
208
|
+
hdr->sequence_number = htonl(hdr->sequence_number);
|
|
209
|
+
hdr->timestamp = htonl(hdr->timestamp);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// Deserialize header from network byte order
|
|
213
|
+
void deserialize_header(MessageHeader *hdr) {
|
|
214
|
+
hdr->message_type = ntohs(hdr->message_type);
|
|
215
|
+
hdr->message_length = ntohs(hdr->message_length);
|
|
216
|
+
hdr->sequence_number = ntohl(hdr->sequence_number);
|
|
217
|
+
hdr->timestamp = ntohl(hdr->timestamp);
|
|
218
|
+
}
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
### ✅ Example 4: Non-Blocking I/O with select()
|
|
222
|
+
|
|
223
|
+
```c
|
|
224
|
+
#include <sys/select.h>
|
|
225
|
+
#include <sys/time.h>
|
|
226
|
+
#include <fcntl.h>
|
|
227
|
+
|
|
228
|
+
int set_nonblocking(int sockfd) {
|
|
229
|
+
int flags = fcntl(sockfd, F_GETFL, 0);
|
|
230
|
+
if (flags < 0) {
|
|
231
|
+
return -1;
|
|
232
|
+
}
|
|
233
|
+
return fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
int handle_multiple_connections(int *sockfds, int count, int timeout_sec) {
|
|
237
|
+
fd_set readfds;
|
|
238
|
+
struct timeval timeout;
|
|
239
|
+
int max_fd = 0;
|
|
240
|
+
int ret;
|
|
241
|
+
|
|
242
|
+
// Set up file descriptor set
|
|
243
|
+
FD_ZERO(&readfds);
|
|
244
|
+
for (int i = 0; i < count; i++) {
|
|
245
|
+
FD_SET(sockfds[i], &readfds);
|
|
246
|
+
if (sockfds[i] > max_fd) {
|
|
247
|
+
max_fd = sockfds[i];
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
// Set timeout
|
|
252
|
+
timeout.tv_sec = timeout_sec;
|
|
253
|
+
timeout.tv_usec = 0;
|
|
254
|
+
|
|
255
|
+
// Wait for activity
|
|
256
|
+
ret = select(max_fd + 1, &readfds, NULL, NULL, &timeout);
|
|
257
|
+
|
|
258
|
+
if (ret < 0) {
|
|
259
|
+
if (errno == EINTR) {
|
|
260
|
+
return 0; // Interrupted, try again
|
|
261
|
+
}
|
|
262
|
+
perror("select");
|
|
263
|
+
return -1;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
if (ret == 0) {
|
|
267
|
+
return 0; // Timeout
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
// Check which sockets have data
|
|
271
|
+
for (int i = 0; i < count; i++) {
|
|
272
|
+
if (FD_ISSET(sockfds[i], &readfds)) {
|
|
273
|
+
handle_socket_data(sockfds[i]);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
return ret;
|
|
278
|
+
}
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
### ✅ Example 5: UDP Socket Communication
|
|
282
|
+
|
|
283
|
+
```c
|
|
284
|
+
#include <sys/socket.h>
|
|
285
|
+
#include <netinet/in.h>
|
|
286
|
+
#include <arpa/inet.h>
|
|
287
|
+
|
|
288
|
+
int create_udp_socket(uint16_t port) {
|
|
289
|
+
int sockfd;
|
|
290
|
+
struct sockaddr_in addr;
|
|
291
|
+
|
|
292
|
+
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
|
|
293
|
+
if (sockfd < 0) {
|
|
294
|
+
perror("socket");
|
|
295
|
+
return -1;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
memset(&addr, 0, sizeof(addr));
|
|
299
|
+
addr.sin_family = AF_INET;
|
|
300
|
+
addr.sin_addr.s_addr = INADDR_ANY;
|
|
301
|
+
addr.sin_port = htons(port);
|
|
302
|
+
|
|
303
|
+
if (bind(sockfd, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
|
|
304
|
+
perror("bind");
|
|
305
|
+
close(sockfd);
|
|
306
|
+
return -1;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
return sockfd;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
ssize_t udp_send(int sockfd, const void *buf, size_t len,
|
|
313
|
+
const char *dest_ip, uint16_t dest_port) {
|
|
314
|
+
struct sockaddr_in dest_addr;
|
|
315
|
+
|
|
316
|
+
memset(&dest_addr, 0, sizeof(dest_addr));
|
|
317
|
+
dest_addr.sin_family = AF_INET;
|
|
318
|
+
dest_addr.sin_port = htons(dest_port);
|
|
319
|
+
|
|
320
|
+
if (inet_pton(AF_INET, dest_ip, &dest_addr.sin_addr) <= 0) {
|
|
321
|
+
return -1;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
return sendto(sockfd, buf, len, 0,
|
|
325
|
+
(struct sockaddr*)&dest_addr, sizeof(dest_addr));
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
ssize_t udp_recv(int sockfd, void *buf, size_t len,
|
|
329
|
+
char *src_ip, size_t ip_len, uint16_t *src_port) {
|
|
330
|
+
struct sockaddr_in src_addr;
|
|
331
|
+
socklen_t addr_len = sizeof(src_addr);
|
|
332
|
+
ssize_t n;
|
|
333
|
+
|
|
334
|
+
n = recvfrom(sockfd, buf, len, 0,
|
|
335
|
+
(struct sockaddr*)&src_addr, &addr_len);
|
|
336
|
+
|
|
337
|
+
if (n > 0 && src_ip != NULL) {
|
|
338
|
+
inet_ntop(AF_INET, &src_addr.sin_addr, src_ip, ip_len);
|
|
339
|
+
if (src_port != NULL) {
|
|
340
|
+
*src_port = ntohs(src_addr.sin_port);
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
return n;
|
|
345
|
+
}
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
### ✅ Example 6: TCP Client Connection
|
|
349
|
+
|
|
350
|
+
```c
|
|
351
|
+
#include <sys/socket.h>
|
|
352
|
+
#include <netinet/in.h>
|
|
353
|
+
#include <arpa/inet.h>
|
|
354
|
+
#include <netdb.h>
|
|
355
|
+
|
|
356
|
+
int connect_to_server(const char *hostname, uint16_t port, int timeout_sec) {
|
|
357
|
+
int sockfd;
|
|
358
|
+
struct addrinfo hints, *result, *rp;
|
|
359
|
+
char port_str[6];
|
|
360
|
+
int ret;
|
|
361
|
+
|
|
362
|
+
// Convert port to string
|
|
363
|
+
snprintf(port_str, sizeof(port_str), "%u", port);
|
|
364
|
+
|
|
365
|
+
// Set up hints
|
|
366
|
+
memset(&hints, 0, sizeof(hints));
|
|
367
|
+
hints.ai_family = AF_UNSPEC; // IPv4 or IPv6
|
|
368
|
+
hints.ai_socktype = SOCK_STREAM;
|
|
369
|
+
|
|
370
|
+
// Resolve hostname
|
|
371
|
+
ret = getaddrinfo(hostname, port_str, &hints, &result);
|
|
372
|
+
if (ret != 0) {
|
|
373
|
+
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(ret));
|
|
374
|
+
return -1;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
// Try each address until we successfully connect
|
|
378
|
+
for (rp = result; rp != NULL; rp = rp->ai_next) {
|
|
379
|
+
sockfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
|
|
380
|
+
if (sockfd < 0) {
|
|
381
|
+
continue;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
// Set timeout
|
|
385
|
+
struct timeval tv;
|
|
386
|
+
tv.tv_sec = timeout_sec;
|
|
387
|
+
tv.tv_usec = 0;
|
|
388
|
+
setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
|
|
389
|
+
setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
|
|
390
|
+
|
|
391
|
+
// Try to connect
|
|
392
|
+
if (connect(sockfd, rp->ai_addr, rp->ai_addrlen) == 0) {
|
|
393
|
+
break; // Success
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
close(sockfd);
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
freeaddrinfo(result);
|
|
400
|
+
|
|
401
|
+
if (rp == NULL) {
|
|
402
|
+
fprintf(stderr, "Could not connect to %s:%u\n", hostname, port);
|
|
403
|
+
return -1;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
return sockfd;
|
|
407
|
+
}
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
### ✅ Example 7: epoll for High-Performance I/O
|
|
411
|
+
|
|
412
|
+
```c
|
|
413
|
+
#include <sys/epoll.h>
|
|
414
|
+
|
|
415
|
+
#define MAX_EVENTS 10
|
|
416
|
+
|
|
417
|
+
int setup_epoll(int listen_sockfd) {
|
|
418
|
+
int epollfd;
|
|
419
|
+
struct epoll_event ev;
|
|
420
|
+
|
|
421
|
+
epollfd = epoll_create1(0);
|
|
422
|
+
if (epollfd < 0) {
|
|
423
|
+
perror("epoll_create1");
|
|
424
|
+
return -1;
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
// Add listen socket to epoll
|
|
428
|
+
ev.events = EPOLLIN;
|
|
429
|
+
ev.data.fd = listen_sockfd;
|
|
430
|
+
|
|
431
|
+
if (epoll_ctl(epollfd, EPOLL_CTL_ADD, listen_sockfd, &ev) < 0) {
|
|
432
|
+
perror("epoll_ctl");
|
|
433
|
+
close(epollfd);
|
|
434
|
+
return -1;
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
return epollfd;
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
void epoll_event_loop(int epollfd, int listen_sockfd) {
|
|
441
|
+
struct epoll_event events[MAX_EVENTS];
|
|
442
|
+
int nfds, n;
|
|
443
|
+
|
|
444
|
+
while (1) {
|
|
445
|
+
nfds = epoll_wait(epollfd, events, MAX_EVENTS, -1);
|
|
446
|
+
if (nfds < 0) {
|
|
447
|
+
if (errno == EINTR) {
|
|
448
|
+
continue;
|
|
449
|
+
}
|
|
450
|
+
perror("epoll_wait");
|
|
451
|
+
break;
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
for (n = 0; n < nfds; n++) {
|
|
455
|
+
if (events[n].data.fd == listen_sockfd) {
|
|
456
|
+
// New connection
|
|
457
|
+
handle_new_connection(epollfd, listen_sockfd);
|
|
458
|
+
} else {
|
|
459
|
+
// Data on existing connection
|
|
460
|
+
handle_client_data(events[n].data.fd);
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
### ✅ Example 8: Protocol State Machine
|
|
468
|
+
|
|
469
|
+
```c
|
|
470
|
+
typedef enum {
|
|
471
|
+
STATE_INIT,
|
|
472
|
+
STATE_CONNECTED,
|
|
473
|
+
STATE_AUTHENTICATED,
|
|
474
|
+
STATE_READY,
|
|
475
|
+
STATE_ERROR,
|
|
476
|
+
STATE_CLOSED
|
|
477
|
+
} ConnectionState;
|
|
478
|
+
|
|
479
|
+
typedef struct {
|
|
480
|
+
int sockfd;
|
|
481
|
+
ConnectionState state;
|
|
482
|
+
uint32_t sequence_number;
|
|
483
|
+
char username[64];
|
|
484
|
+
} Connection;
|
|
485
|
+
|
|
486
|
+
int handle_protocol_message(Connection *conn, const void *data, size_t len) {
|
|
487
|
+
MessageHeader *hdr = (MessageHeader*)data;
|
|
488
|
+
|
|
489
|
+
// Validate message
|
|
490
|
+
if (len < sizeof(MessageHeader)) {
|
|
491
|
+
conn->state = STATE_ERROR;
|
|
492
|
+
return -1;
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
deserialize_header(hdr);
|
|
496
|
+
|
|
497
|
+
// State machine
|
|
498
|
+
switch (conn->state) {
|
|
499
|
+
case STATE_CONNECTED:
|
|
500
|
+
if (hdr->message_type == MSG_AUTH_REQUEST) {
|
|
501
|
+
if (authenticate_user(conn, data, len)) {
|
|
502
|
+
conn->state = STATE_AUTHENTICATED;
|
|
503
|
+
send_auth_response(conn, true);
|
|
504
|
+
} else {
|
|
505
|
+
conn->state = STATE_ERROR;
|
|
506
|
+
send_auth_response(conn, false);
|
|
507
|
+
}
|
|
508
|
+
} else {
|
|
509
|
+
conn->state = STATE_ERROR;
|
|
510
|
+
return -1;
|
|
511
|
+
}
|
|
512
|
+
break;
|
|
513
|
+
|
|
514
|
+
case STATE_AUTHENTICATED:
|
|
515
|
+
if (hdr->message_type == MSG_READY) {
|
|
516
|
+
conn->state = STATE_READY;
|
|
517
|
+
}
|
|
518
|
+
break;
|
|
519
|
+
|
|
520
|
+
case STATE_READY:
|
|
521
|
+
// Handle normal messages
|
|
522
|
+
process_message(conn, hdr, data, len);
|
|
523
|
+
break;
|
|
524
|
+
|
|
525
|
+
default:
|
|
526
|
+
conn->state = STATE_ERROR;
|
|
527
|
+
return -1;
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
return 0;
|
|
531
|
+
}
|
|
532
|
+
```
|
|
533
|
+
|
|
534
|
+
### ✅ Example 9: Socket Options Configuration
|
|
535
|
+
|
|
536
|
+
```c
|
|
537
|
+
int configure_socket_options(int sockfd) {
|
|
538
|
+
int opt;
|
|
539
|
+
struct linger linger_opt;
|
|
540
|
+
struct timeval timeout;
|
|
541
|
+
|
|
542
|
+
// Enable address reuse
|
|
543
|
+
opt = 1;
|
|
544
|
+
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) {
|
|
545
|
+
perror("SO_REUSEADDR");
|
|
546
|
+
return -1;
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
// Enable keepalive
|
|
550
|
+
opt = 1;
|
|
551
|
+
if (setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, &opt, sizeof(opt)) < 0) {
|
|
552
|
+
perror("SO_KEEPALIVE");
|
|
553
|
+
return -1;
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
// Set send/receive timeouts
|
|
557
|
+
timeout.tv_sec = 30;
|
|
558
|
+
timeout.tv_usec = 0;
|
|
559
|
+
setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
|
|
560
|
+
setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout));
|
|
561
|
+
|
|
562
|
+
// Configure linger (wait for data to be sent on close)
|
|
563
|
+
linger_opt.l_onoff = 1;
|
|
564
|
+
linger_opt.l_linger = 5; // 5 seconds
|
|
565
|
+
if (setsockopt(sockfd, SOL_SOCKET, SO_LINGER, &linger_opt, sizeof(linger_opt)) < 0) {
|
|
566
|
+
perror("SO_LINGER");
|
|
567
|
+
return -1;
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
// Disable Nagle's algorithm for low-latency
|
|
571
|
+
opt = 1;
|
|
572
|
+
if (setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt)) < 0) {
|
|
573
|
+
perror("TCP_NODELAY");
|
|
574
|
+
return -1;
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
return 0;
|
|
578
|
+
}
|
|
579
|
+
```
|
|
580
|
+
|
|
581
|
+
### ✅ Example 10: Packet Validation
|
|
582
|
+
|
|
583
|
+
```c
|
|
584
|
+
#include <stdint.h>
|
|
585
|
+
#include <stdbool.h>
|
|
586
|
+
|
|
587
|
+
#define MAX_PACKET_SIZE 65535
|
|
588
|
+
#define MIN_PACKET_SIZE sizeof(MessageHeader)
|
|
589
|
+
|
|
590
|
+
bool validate_packet(const void *data, size_t len) {
|
|
591
|
+
const MessageHeader *hdr;
|
|
592
|
+
|
|
593
|
+
// Check minimum size
|
|
594
|
+
if (len < MIN_PACKET_SIZE) {
|
|
595
|
+
return false;
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
// Check maximum size
|
|
599
|
+
if (len > MAX_PACKET_SIZE) {
|
|
600
|
+
return false;
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
hdr = (const MessageHeader*)data;
|
|
604
|
+
|
|
605
|
+
// Validate header fields (after byte order conversion)
|
|
606
|
+
MessageHeader temp_hdr = *hdr;
|
|
607
|
+
deserialize_header(&temp_hdr);
|
|
608
|
+
|
|
609
|
+
// Check message length matches actual length
|
|
610
|
+
if (temp_hdr.message_length != len) {
|
|
611
|
+
return false;
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
// Validate message type
|
|
615
|
+
if (temp_hdr.message_type >= MSG_TYPE_MAX) {
|
|
616
|
+
return false;
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
// Check sequence number (should be monotonically increasing)
|
|
620
|
+
// ... additional validation ...
|
|
621
|
+
|
|
622
|
+
return true;
|
|
623
|
+
}
|
|
624
|
+
```
|
|
625
|
+
|
|
626
|
+
### ✅ Example 11: Graceful Connection Shutdown
|
|
627
|
+
|
|
628
|
+
```c
|
|
629
|
+
int graceful_shutdown(int sockfd) {
|
|
630
|
+
char buf[256];
|
|
631
|
+
ssize_t n;
|
|
632
|
+
int ret;
|
|
633
|
+
|
|
634
|
+
// Shutdown write side (send FIN)
|
|
635
|
+
ret = shutdown(sockfd, SHUT_WR);
|
|
636
|
+
if (ret < 0) {
|
|
637
|
+
perror("shutdown");
|
|
638
|
+
close(sockfd);
|
|
639
|
+
return -1;
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
// Read remaining data until peer closes
|
|
643
|
+
while (1) {
|
|
644
|
+
n = recv(sockfd, buf, sizeof(buf), 0);
|
|
645
|
+
if (n <= 0) {
|
|
646
|
+
break; // Connection closed or error
|
|
647
|
+
}
|
|
648
|
+
// Discard data
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
// Close socket
|
|
652
|
+
close(sockfd);
|
|
653
|
+
return 0;
|
|
654
|
+
}
|
|
655
|
+
```
|
|
656
|
+
|
|
657
|
+
### ✅ Example 12: IPv6 Support
|
|
658
|
+
|
|
659
|
+
```c
|
|
660
|
+
int create_dual_stack_server(uint16_t port) {
|
|
661
|
+
int sockfd;
|
|
662
|
+
struct sockaddr_in6 addr;
|
|
663
|
+
int opt = 1;
|
|
664
|
+
|
|
665
|
+
// Create IPv6 socket
|
|
666
|
+
sockfd = socket(AF_INET6, SOCK_STREAM, 0);
|
|
667
|
+
if (sockfd < 0) {
|
|
668
|
+
perror("socket");
|
|
669
|
+
return -1;
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
// Enable address reuse
|
|
673
|
+
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
|
|
674
|
+
|
|
675
|
+
// Disable IPv6-only mode (allow IPv4 connections)
|
|
676
|
+
opt = 0;
|
|
677
|
+
if (setsockopt(sockfd, IPPROTO_IPV6, IPV6_V6ONLY, &opt, sizeof(opt)) < 0) {
|
|
678
|
+
perror("IPV6_V6ONLY");
|
|
679
|
+
close(sockfd);
|
|
680
|
+
return -1;
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
// Bind to all interfaces
|
|
684
|
+
memset(&addr, 0, sizeof(addr));
|
|
685
|
+
addr.sin6_family = AF_INET6;
|
|
686
|
+
addr.sin6_addr = in6addr_any;
|
|
687
|
+
addr.sin6_port = htons(port);
|
|
688
|
+
|
|
689
|
+
if (bind(sockfd, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
|
|
690
|
+
perror("bind");
|
|
691
|
+
close(sockfd);
|
|
692
|
+
return -1;
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
if (listen(sockfd, 5) < 0) {
|
|
696
|
+
perror("listen");
|
|
697
|
+
close(sockfd);
|
|
698
|
+
return -1;
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
return sockfd;
|
|
702
|
+
}
|
|
703
|
+
```
|
|
704
|
+
|
|
705
|
+
## References
|
|
706
|
+
|
|
707
|
+
- POSIX.1-2017 Sockets API
|
|
708
|
+
- Stevens, W. Richard. "Unix Network Programming"
|
|
709
|
+
- RFC 793 (TCP), RFC 768 (UDP), RFC 791 (IP)
|
|
710
|
+
- Beej's Guide to Network Programming
|
|
711
|
+
- Linux Socket Programming by Example
|
|
712
|
+
|
|
713
|
+
## Related Rules
|
|
714
|
+
|
|
715
|
+
- category-systems
|
|
716
|
+
- universal-error-handling
|
|
717
|
+
- universal-memory-safety
|
|
718
|
+
|
|
719
|
+
## Configuration
|
|
720
|
+
|
|
721
|
+
Enable in `.augment/c-standards.json`:
|
|
722
|
+
|
|
723
|
+
```json
|
|
724
|
+
{
|
|
725
|
+
"categories": ["networking"],
|
|
726
|
+
"category_overrides": {
|
|
727
|
+
"networking": {
|
|
728
|
+
"require_byte_order_conversion": true,
|
|
729
|
+
"check_partial_transfers": true,
|
|
730
|
+
"enforce_timeout_handling": true
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
}
|
|
734
|
+
```
|
|
735
|
+
|