commit 81d004b7644d9871420abd06cef84b8bc667e535
parent 9621d56ec9bd1dac721633dc8ee5c8151f4f39bd
Author: Robin Bron <robin.bron@yourhosting.nl>
Date: Mon, 2 Mar 2026 15:33:56 +0100
auto-formatting
Diffstat:
28 files changed, 1114 insertions(+), 675 deletions(-)
diff --git a/.clang-format b/.clang-format
@@ -0,0 +1,334 @@
+---
+Language: Cpp
+AccessModifierOffset: -1
+AlignAfterOpenBracket: Align
+AlignArrayOfStructures: None
+AlignConsecutiveAssignments:
+ Enabled: true
+ AcrossEmptyLines: false
+ AcrossComments: false
+ AlignCompound: false
+ AlignFunctionDeclarations: false
+ AlignFunctionPointers: false
+ PadOperators: true
+AlignConsecutiveBitFields:
+ Enabled: false
+ AcrossEmptyLines: false
+ AcrossComments: false
+ AlignCompound: false
+ AlignFunctionDeclarations: false
+ AlignFunctionPointers: false
+ PadOperators: false
+AlignConsecutiveDeclarations:
+ Enabled: true
+ AcrossEmptyLines: false
+ AcrossComments: false
+ AlignCompound: false
+ AlignFunctionDeclarations: true
+ AlignFunctionPointers: false
+ PadOperators: false
+AlignConsecutiveMacros:
+ Enabled: true
+ AcrossEmptyLines: false
+ AcrossComments: false
+ AlignCompound: false
+ AlignFunctionDeclarations: false
+ AlignFunctionPointers: false
+ PadOperators: false
+AlignConsecutiveShortCaseStatements:
+ Enabled: true
+ AcrossEmptyLines: false
+ AcrossComments: false
+ AlignCaseArrows: false
+ AlignCaseColons: false
+AlignConsecutiveTableGenBreakingDAGArgColons:
+ Enabled: false
+ AcrossEmptyLines: false
+ AcrossComments: false
+ AlignCompound: false
+ AlignFunctionDeclarations: false
+ AlignFunctionPointers: false
+ PadOperators: false
+AlignConsecutiveTableGenCondOperatorColons:
+ Enabled: false
+ AcrossEmptyLines: false
+ AcrossComments: false
+ AlignCompound: false
+ AlignFunctionDeclarations: false
+ AlignFunctionPointers: false
+ PadOperators: false
+AlignConsecutiveTableGenDefinitionColons:
+ Enabled: false
+ AcrossEmptyLines: false
+ AcrossComments: false
+ AlignCompound: false
+ AlignFunctionDeclarations: false
+ AlignFunctionPointers: false
+ PadOperators: false
+AlignEscapedNewlines: Left
+AlignOperands: Align
+AlignTrailingComments:
+ Kind: Always
+ OverEmptyLines: 0
+AllowAllArgumentsOnNextLine: true
+AllowAllParametersOfDeclarationOnNextLine: true
+AllowBreakBeforeNoexceptSpecifier: Never
+AllowShortBlocksOnASingleLine: Never
+AllowShortCaseExpressionOnASingleLine: true
+AllowShortCaseLabelsOnASingleLine: false
+AllowShortCompoundRequirementOnASingleLine: true
+AllowShortEnumsOnASingleLine: true
+AllowShortFunctionsOnASingleLine: None
+AllowShortIfStatementsOnASingleLine: WithoutElse
+AllowShortLambdasOnASingleLine: All
+AllowShortLoopsOnASingleLine: true
+AllowShortNamespacesOnASingleLine: false
+AlwaysBreakAfterDefinitionReturnType: None
+AlwaysBreakBeforeMultilineStrings: true
+AttributeMacros:
+ - __capability
+ - absl_nonnull
+ - absl_nullable
+ - absl_nullability_unknown
+BinPackArguments: true
+BinPackLongBracedList: true
+BinPackParameters: BinPack
+BitFieldColonSpacing: Both
+BracedInitializerIndentWidth: -1
+BraceWrapping:
+ AfterCaseLabel: false
+ AfterClass: false
+ AfterControlStatement: Never
+ AfterEnum: false
+ AfterExternBlock: false
+ AfterFunction: true
+ AfterNamespace: false
+ AfterObjCDeclaration: false
+ AfterStruct: false
+ AfterUnion: false
+ BeforeCatch: false
+ BeforeElse: false
+ BeforeLambdaBody: false
+ BeforeWhile: false
+ IndentBraces: false
+ SplitEmptyFunction: true
+ SplitEmptyRecord: true
+ SplitEmptyNamespace: true
+BreakAdjacentStringLiterals: true
+BreakAfterAttributes: Leave
+BreakAfterJavaFieldAnnotations: false
+BreakAfterReturnType: None
+BreakArrays: true
+BreakBeforeBinaryOperators: None
+BreakBeforeConceptDeclarations: Always
+BreakBeforeBraces: Attach
+BreakBeforeInlineASMColon: OnlyMultiline
+BreakBeforeTemplateCloser: false
+BreakBeforeTernaryOperators: true
+BreakBinaryOperations: Never
+BreakConstructorInitializers: BeforeColon
+BreakFunctionDefinitionParameters: false
+BreakInheritanceList: BeforeColon
+BreakStringLiterals: true
+BreakTemplateDeclarations: Yes
+ColumnLimit: 120
+CommentPragmas: '^ IWYU pragma:'
+CompactNamespaces: false
+ConstructorInitializerIndentWidth: 4
+ContinuationIndentWidth: 4
+Cpp11BracedListStyle: true
+DerivePointerAlignment: false
+DisableFormat: false
+EmptyLineAfterAccessModifier: Never
+EmptyLineBeforeAccessModifier: LogicalBlock
+EnumTrailingComma: Leave
+ExperimentalAutoDetectBinPacking: false
+FixNamespaceComments: true
+ForEachMacros:
+ - foreach
+ - Q_FOREACH
+ - BOOST_FOREACH
+IfMacros:
+ - KJ_IF_MAYBE
+IncludeBlocks: Regroup
+IncludeCategories:
+ - Regex: '^<ext/.*\.h>'
+ Priority: 2
+ SortPriority: 0
+ CaseSensitive: false
+ - Regex: '^<.*\.h>'
+ Priority: 1
+ SortPriority: 0
+ CaseSensitive: false
+ - Regex: '^<.*'
+ Priority: 2
+ SortPriority: 0
+ CaseSensitive: false
+ - Regex: '.*'
+ Priority: 3
+ SortPriority: 0
+ CaseSensitive: false
+IncludeIsMainRegex: '([-_](test|unittest))?$'
+IncludeIsMainSourceRegex: ''
+IndentAccessModifiers: false
+IndentCaseBlocks: true
+IndentCaseLabels: true
+IndentExportBlock: true
+IndentExternBlock: AfterExternBlock
+IndentGotoLabels: true
+IndentPPDirectives: None
+IndentRequiresClause: true
+IndentWidth: 2
+IndentWrappedFunctionNames: false
+InsertBraces: false
+InsertNewlineAtEOF: true
+InsertTrailingCommas: None
+IntegerLiteralSeparator:
+ Binary: 0
+ BinaryMinDigits: 0
+ Decimal: 0
+ DecimalMinDigits: 0
+ Hex: 0
+ HexMinDigits: 0
+JavaScriptQuotes: Leave
+JavaScriptWrapImports: true
+KeepEmptyLines:
+ AtEndOfFile: false
+ AtStartOfBlock: false
+ AtStartOfFile: false
+KeepFormFeed: false
+LambdaBodyIndentation: Signature
+LineEnding: DeriveLF
+MacroBlockBegin: ''
+MacroBlockEnd: ''
+MainIncludeChar: Quote
+MaxEmptyLinesToKeep: 1
+NamespaceIndentation: None
+ObjCBinPackProtocolList: Never
+ObjCBlockIndentWidth: 2
+ObjCBreakBeforeNestedBlockParam: true
+ObjCSpaceAfterProperty: false
+ObjCSpaceBeforeProtocolList: true
+OneLineFormatOffRegex: ''
+PackConstructorInitializers: NextLine
+PenaltyBreakAssignment: 2
+PenaltyBreakBeforeFirstCallParameter: 1
+PenaltyBreakBeforeMemberAccess: 150
+PenaltyBreakComment: 300
+PenaltyBreakFirstLessLess: 120
+PenaltyBreakOpenParenthesis: 0
+PenaltyBreakScopeResolution: 500
+PenaltyBreakString: 1000
+PenaltyBreakTemplateDeclaration: 10
+PenaltyExcessCharacter: 1000000
+PenaltyIndentedWhitespace: 0
+PenaltyReturnTypeOnItsOwnLine: 200
+PointerAlignment: Right
+PPIndentWidth: -1
+QualifierAlignment: Leave
+RawStringFormats:
+ - Language: Cpp
+ Delimiters:
+ - cc
+ - CC
+ - cpp
+ - Cpp
+ - CPP
+ - 'c++'
+ - 'C++'
+ CanonicalDelimiter: ''
+ BasedOnStyle: google
+ - Language: TextProto
+ Delimiters:
+ - pb
+ - PB
+ - proto
+ - PROTO
+ EnclosingFunctions:
+ - EqualsProto
+ - EquivToProto
+ - PARSE_PARTIAL_TEXT_PROTO
+ - PARSE_TEST_PROTO
+ - PARSE_TEXT_PROTO
+ - ParseTextOrDie
+ - ParseTextProtoOrDie
+ - ParseTestProto
+ - ParsePartialTestProto
+ CanonicalDelimiter: pb
+ BasedOnStyle: google
+ReferenceAlignment: Pointer
+ReflowComments: Always
+RemoveBracesLLVM: false
+RemoveEmptyLinesInUnwrappedLines: false
+RemoveParentheses: Leave
+RemoveSemicolon: false
+RequiresClausePosition: OwnLine
+RequiresExpressionIndentation: OuterScope
+SeparateDefinitionBlocks: Leave
+ShortNamespaceLines: 1
+SkipMacroDefinitionBody: false
+SortIncludes:
+ Enabled: true
+ IgnoreCase: false
+SortJavaStaticImport: Before
+SortUsingDeclarations: LexicographicNumeric
+SpaceAfterCStyleCast: false
+SpaceAfterLogicalNot: false
+SpaceAfterOperatorKeyword: false
+SpaceAfterTemplateKeyword: true
+SpaceAroundPointerQualifiers: Default
+SpaceBeforeAssignmentOperators: true
+SpaceBeforeCaseColon: false
+SpaceBeforeCpp11BracedList: false
+SpaceBeforeCtorInitializerColon: true
+SpaceBeforeInheritanceColon: true
+SpaceBeforeJsonColon: false
+SpaceBeforeParens: ControlStatements
+SpaceBeforeParensOptions:
+ AfterControlStatements: true
+ AfterForeachMacros: true
+ AfterFunctionDefinitionName: false
+ AfterFunctionDeclarationName: false
+ AfterIfMacros: true
+ AfterNot: false
+ AfterOverloadedOperator: false
+ AfterPlacementOperator: true
+ AfterRequiresInClause: false
+ AfterRequiresInExpression: false
+ BeforeNonEmptyParentheses: false
+SpaceBeforeRangeBasedForLoopColon: true
+SpaceBeforeSquareBrackets: false
+SpaceInEmptyBlock: false
+SpacesBeforeTrailingComments: 2
+SpacesInAngles: Never
+SpacesInContainerLiterals: true
+SpacesInLineCommentPrefix:
+ Minimum: 1
+ Maximum: -1
+SpacesInParens: Never
+SpacesInParensOptions:
+ ExceptDoubleParentheses: false
+ InCStyleCasts: false
+ InConditionalStatements: false
+ InEmptyParentheses: false
+ Other: false
+SpacesInSquareBrackets: false
+Standard: Auto
+StatementAttributeLikeMacros:
+ - Q_EMIT
+StatementMacros:
+ - Q_UNUSED
+ - QT_REQUIRE_VERSION
+TableGenBreakInsideDAGArg: DontBreak
+TabWidth: 8
+UseTab: Never
+VerilogBreakBetweenInstancePorts: true
+WhitespaceSensitiveMacros:
+ - BOOST_PP_STRINGIZE
+ - CF_SWIFT_NAME
+ - NS_SWIFT_NAME
+ - PP_STRINGIZE
+ - STRINGIZE
+WrapNamespaceBodyWithEmptyLines: Leave
+...
+
diff --git a/Makefile b/Makefile
@@ -131,3 +131,7 @@ clean:
rm -rf $(BIN) $(BIN).1
rm -rf $(OBJ)
rm -rf doc/cli_doc.md doc/cli_doc.man doc/license.man
+
+.PHONY: format
+format:
+ $(FIND) src/ -type f \( -name '*.c' -o -name '*.h' \) -exec clang-format -i {} +
diff --git a/src/common/resp.c b/src/common/resp.c
@@ -1,14 +1,15 @@
+#include "common/resp.h"
+
+#include <errno.h>
+#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <stdio.h>
#include <unistd.h>
-#include <errno.h>
#include "rxi/log.h"
-#include "common/resp.h"
-#define MAX_BULK_LEN (256 * 1024)
-#define LINE_BUF 4096
+#define MAX_BULK_LEN (256 * 1024)
+#define LINE_BUF 4096
static void resp_free_internal(resp_object *o);
@@ -21,8 +22,8 @@ static int resp_read_byte_from_buf(const char **buf, size_t *len) {
}
static int resp_read_line_from_buf(const char **buf, size_t *len, char *out, size_t out_size) {
- size_t i = 0;
- int prev = -1;
+ size_t i = 0;
+ int prev = -1;
while (i + 1 < out_size) {
if (*len < 1) return -1;
int b = (int)(unsigned char)(*buf)[0];
@@ -32,15 +33,15 @@ static int resp_read_line_from_buf(const char **buf, size_t *len, char *out, siz
out[i - 1] = '\0';
return 0;
}
- prev = b;
+ prev = b;
out[i++] = (char)b;
}
return -1;
}
resp_object *resp_read_buf(const char *buf, size_t len) {
- const char *p = buf;
- size_t remaining = len;
+ const char *p = buf;
+ size_t remaining = len;
int type_c = resp_read_byte_from_buf(&p, &remaining);
if (type_c < 0) return NULL;
@@ -51,66 +52,111 @@ resp_object *resp_read_buf(const char *buf, size_t len) {
switch ((char)type_c) {
case '+':
o->type = RESPT_SIMPLE;
- if (resp_read_line_from_buf(&p, &remaining, line, sizeof(line)) != 0) { free(o); return NULL; }
+ if (resp_read_line_from_buf(&p, &remaining, line, sizeof(line)) != 0) {
+ free(o);
+ return NULL;
+ }
o->u.s = strdup(line);
break;
case '-':
o->type = RESPT_ERROR;
- if (resp_read_line_from_buf(&p, &remaining, line, sizeof(line)) != 0) { free(o); return NULL; }
+ if (resp_read_line_from_buf(&p, &remaining, line, sizeof(line)) != 0) {
+ free(o);
+ return NULL;
+ }
o->u.s = strdup(line);
break;
- case ':': {
- if (resp_read_line_from_buf(&p, &remaining, line, sizeof(line)) != 0) { free(o); return NULL; }
- o->type = RESPT_INT;
- o->u.i = (long long)strtoll(line, NULL, 10);
- break;
- }
- case '$': {
- if (resp_read_line_from_buf(&p, &remaining, line, sizeof(line)) != 0) { free(o); return NULL; }
- long blen = strtol(line, NULL, 10);
- if (blen < 0 || blen > (long)MAX_BULK_LEN) { free(o); return NULL; }
- o->type = RESPT_BULK;
- if (blen == 0) {
- o->u.s = strdup("");
- if (resp_read_line_from_buf(&p, &remaining, line, sizeof(line)) != 0) { free(o->u.s); free(o); return NULL; }
- } else {
- if ((size_t)blen > remaining) { free(o); return NULL; }
- o->u.s = malloc((size_t)blen + 1);
- if (!o->u.s) { free(o); return NULL; }
- memcpy(o->u.s, p, (size_t)blen);
- p += blen;
- remaining -= (size_t)blen;
- o->u.s[blen] = '\0';
- if (remaining < 2) { free(o->u.s); free(o); return NULL; }
- if (p[0] != '\r' || p[1] != '\n') { free(o->u.s); free(o); return NULL; }
- p += 2;
- remaining -= 2;
+ case ':':
+ {
+ if (resp_read_line_from_buf(&p, &remaining, line, sizeof(line)) != 0) {
+ free(o);
+ return NULL;
+ }
+ o->type = RESPT_INT;
+ o->u.i = (long long)strtoll(line, NULL, 10);
+ break;
}
- break;
- }
- case '*': {
- if (resp_read_line_from_buf(&p, &remaining, line, sizeof(line)) != 0) { free(o); return NULL; }
- long n = strtol(line, NULL, 10);
- if (n < 0 || n > 65536) { free(o); return NULL; }
- o->type = RESPT_ARRAY;
- o->u.arr.n = (size_t)n;
- o->u.arr.elem = n ? calloc((size_t)n, sizeof(resp_object)) : NULL;
- if (n && !o->u.arr.elem) { free(o); return NULL; }
- for (size_t i = 0; i < (size_t)n; i++) {
- resp_object *sub = resp_read_buf(p, remaining);
- if (!sub) {
- for (size_t j = 0; j < i; j++) resp_free_internal(&o->u.arr.elem[j]);
- free(o->u.arr.elem);
+ case '$':
+ {
+ if (resp_read_line_from_buf(&p, &remaining, line, sizeof(line)) != 0) {
+ free(o);
+ return NULL;
+ }
+ long blen = strtol(line, NULL, 10);
+ if (blen < 0 || blen > (long)MAX_BULK_LEN) {
free(o);
return NULL;
}
- p += remaining - (sub ? remaining : 0);
- remaining = 0;
- o->u.arr.elem[i] = *sub;
- free(sub);
+ o->type = RESPT_BULK;
+ if (blen == 0) {
+ o->u.s = strdup("");
+ if (resp_read_line_from_buf(&p, &remaining, line, sizeof(line)) != 0) {
+ free(o->u.s);
+ free(o);
+ return NULL;
+ }
+ } else {
+ if ((size_t)blen > remaining) {
+ free(o);
+ return NULL;
+ }
+ o->u.s = malloc((size_t)blen + 1);
+ if (!o->u.s) {
+ free(o);
+ return NULL;
+ }
+ memcpy(o->u.s, p, (size_t)blen);
+ p += blen;
+ remaining -= (size_t)blen;
+ o->u.s[blen] = '\0';
+ if (remaining < 2) {
+ free(o->u.s);
+ free(o);
+ return NULL;
+ }
+ if (p[0] != '\r' || p[1] != '\n') {
+ free(o->u.s);
+ free(o);
+ return NULL;
+ }
+ p += 2;
+ remaining -= 2;
+ }
+ break;
+ }
+ case '*':
+ {
+ if (resp_read_line_from_buf(&p, &remaining, line, sizeof(line)) != 0) {
+ free(o);
+ return NULL;
+ }
+ long n = strtol(line, NULL, 10);
+ if (n < 0 || n > 65536) {
+ free(o);
+ return NULL;
+ }
+ o->type = RESPT_ARRAY;
+ o->u.arr.n = (size_t)n;
+ o->u.arr.elem = n ? calloc((size_t)n, sizeof(resp_object)) : NULL;
+ if (n && !o->u.arr.elem) {
+ free(o);
+ return NULL;
+ }
+ for (size_t i = 0; i < (size_t)n; i++) {
+ resp_object *sub = resp_read_buf(p, remaining);
+ if (!sub) {
+ for (size_t j = 0; j < i; j++) resp_free_internal(&o->u.arr.elem[j]);
+ free(o->u.arr.elem);
+ free(o);
+ return NULL;
+ }
+ p += remaining - (sub ? remaining : 0);
+ remaining = 0;
+ o->u.arr.elem[i] = *sub;
+ free(sub);
+ }
+ break;
}
- break;
- }
default:
free(o);
return NULL;
@@ -120,18 +166,17 @@ resp_object *resp_read_buf(const char *buf, size_t len) {
static int resp_read_byte(int fd) {
unsigned char c;
- ssize_t n = read(fd, &c, 1);
+ ssize_t n = read(fd, &c, 1);
if (n != 1) {
- if (n < 0 && (errno == EAGAIN || errno == EWOULDBLOCK))
- return -2;
+ if (n < 0 && (errno == EAGAIN || errno == EWOULDBLOCK)) return -2;
return -1;
}
return (int)c;
}
static int resp_read_line(int fd, char *buf, size_t buf_size) {
- size_t i = 0;
- int prev = -1;
+ size_t i = 0;
+ int prev = -1;
while (i + 1 < buf_size) {
int b = resp_read_byte(fd);
if (b < 0) return -1;
@@ -139,7 +184,7 @@ static int resp_read_line(int fd, char *buf, size_t buf_size) {
buf[i - 1] = '\0';
return 0;
}
- prev = b;
+ prev = b;
buf[i++] = (char)b;
}
return -1;
@@ -155,58 +200,100 @@ resp_object *resp_read(int fd) {
switch ((char)type_c) {
case '+':
o->type = RESPT_SIMPLE;
- if (resp_read_line(fd, line, sizeof(line)) != 0) { free(o); return NULL; }
+ if (resp_read_line(fd, line, sizeof(line)) != 0) {
+ free(o);
+ return NULL;
+ }
o->u.s = strdup(line);
break;
case '-':
o->type = RESPT_ERROR;
- if (resp_read_line(fd, line, sizeof(line)) != 0) { free(o); return NULL; }
+ if (resp_read_line(fd, line, sizeof(line)) != 0) {
+ free(o);
+ return NULL;
+ }
o->u.s = strdup(line);
break;
- case ':': {
- if (resp_read_line(fd, line, sizeof(line)) != 0) { free(o); return NULL; }
- o->type = RESPT_INT;
- o->u.i = (long long)strtoll(line, NULL, 10);
- break;
- }
- case '$': {
- if (resp_read_line(fd, line, sizeof(line)) != 0) { free(o); return NULL; }
- long len = strtol(line, NULL, 10);
- if (len < 0 || len > (long)MAX_BULK_LEN) { free(o); return NULL; }
- o->type = RESPT_BULK;
- if (len == 0) {
- o->u.s = strdup("");
- if (resp_read_line(fd, line, sizeof(line)) != 0) { free(o->u.s); free(o); return NULL; }
- } else {
- o->u.s = malloc((size_t)len + 1);
- if (!o->u.s) { free(o); return NULL; }
- if (read(fd, o->u.s, (size_t)len) != (ssize_t)len) { free(o->u.s); free(o); return NULL; }
- o->u.s[len] = '\0';
- if (resp_read_byte(fd) != '\r' || resp_read_byte(fd) != '\n') { free(o->u.s); free(o); return NULL; }
+ case ':':
+ {
+ if (resp_read_line(fd, line, sizeof(line)) != 0) {
+ free(o);
+ return NULL;
+ }
+ o->type = RESPT_INT;
+ o->u.i = (long long)strtoll(line, NULL, 10);
+ break;
}
- break;
- }
- case '*': {
- if (resp_read_line(fd, line, sizeof(line)) != 0) { free(o); return NULL; }
- long n = strtol(line, NULL, 10);
- if (n < 0 || n > 65536) { free(o); return NULL; }
- o->type = RESPT_ARRAY;
- o->u.arr.n = (size_t)n;
- o->u.arr.elem = n ? calloc((size_t)n, sizeof(resp_object)) : NULL;
- if (n && !o->u.arr.elem) { free(o); return NULL; }
- for (size_t i = 0; i < (size_t)n; i++) {
- resp_object *sub = resp_read(fd);
- if (!sub) {
- for (size_t j = 0; j < i; j++) resp_free_internal(&o->u.arr.elem[j]);
- free(o->u.arr.elem);
+ case '$':
+ {
+ if (resp_read_line(fd, line, sizeof(line)) != 0) {
+ free(o);
+ return NULL;
+ }
+ long len = strtol(line, NULL, 10);
+ if (len < 0 || len > (long)MAX_BULK_LEN) {
free(o);
return NULL;
}
- o->u.arr.elem[i] = *sub;
- free(sub);
+ o->type = RESPT_BULK;
+ if (len == 0) {
+ o->u.s = strdup("");
+ if (resp_read_line(fd, line, sizeof(line)) != 0) {
+ free(o->u.s);
+ free(o);
+ return NULL;
+ }
+ } else {
+ o->u.s = malloc((size_t)len + 1);
+ if (!o->u.s) {
+ free(o);
+ return NULL;
+ }
+ if (read(fd, o->u.s, (size_t)len) != (ssize_t)len) {
+ free(o->u.s);
+ free(o);
+ return NULL;
+ }
+ o->u.s[len] = '\0';
+ if (resp_read_byte(fd) != '\r' || resp_read_byte(fd) != '\n') {
+ free(o->u.s);
+ free(o);
+ return NULL;
+ }
+ }
+ break;
+ }
+ case '*':
+ {
+ if (resp_read_line(fd, line, sizeof(line)) != 0) {
+ free(o);
+ return NULL;
+ }
+ long n = strtol(line, NULL, 10);
+ if (n < 0 || n > 65536) {
+ free(o);
+ return NULL;
+ }
+ o->type = RESPT_ARRAY;
+ o->u.arr.n = (size_t)n;
+ o->u.arr.elem = n ? calloc((size_t)n, sizeof(resp_object)) : NULL;
+ if (n && !o->u.arr.elem) {
+ free(o);
+ return NULL;
+ }
+ for (size_t i = 0; i < (size_t)n; i++) {
+ resp_object *sub = resp_read(fd);
+ if (!sub) {
+ for (size_t j = 0; j < i; j++) resp_free_internal(&o->u.arr.elem[j]);
+ free(o->u.arr.elem);
+ free(o);
+ return NULL;
+ }
+ o->u.arr.elem[i] = *sub;
+ free(sub);
+ }
+ break;
}
- break;
- }
default:
free(o);
return NULL;
@@ -219,8 +306,7 @@ static void resp_free_internal(resp_object *o) {
if (o->type == RESPT_SIMPLE || o->type == RESPT_ERROR || o->type == RESPT_BULK) {
free(o->u.s);
} else if (o->type == RESPT_ARRAY) {
- for (size_t i = 0; i < o->u.arr.n; i++)
- resp_free_internal(&o->u.arr.elem[i]);
+ for (size_t i = 0; i < o->u.arr.n; i++) resp_free_internal(&o->u.arr.elem[i]);
free(o->u.arr.elem);
}
}
@@ -237,7 +323,10 @@ resp_object *resp_deep_copy(const resp_object *o) {
c->type = o->type;
if (o->type == RESPT_SIMPLE || o->type == RESPT_ERROR || o->type == RESPT_BULK) {
c->u.s = o->u.s ? strdup(o->u.s) : NULL;
- if (o->u.s && !c->u.s) { free(c); return NULL; }
+ if (o->u.s && !c->u.s) {
+ free(c);
+ return NULL;
+ }
return c;
}
if (o->type == RESPT_INT) {
@@ -245,9 +334,12 @@ resp_object *resp_deep_copy(const resp_object *o) {
return c;
}
if (o->type == RESPT_ARRAY) {
- c->u.arr.n = o->u.arr.n;
+ c->u.arr.n = o->u.arr.n;
c->u.arr.elem = o->u.arr.n ? (resp_object *)calloc(o->u.arr.n, sizeof(resp_object)) : NULL;
- if (o->u.arr.n && !c->u.arr.elem) { free(c); return NULL; }
+ if (o->u.arr.n && !c->u.arr.elem) {
+ free(c);
+ return NULL;
+ }
for (size_t i = 0; i < o->u.arr.n; i++) {
resp_object *sub = resp_deep_copy(&o->u.arr.elem[i]);
if (!sub) {
@@ -271,9 +363,8 @@ resp_object *resp_map_get(const resp_object *o, const char *key) {
if (n & 1) return NULL;
for (size_t i = 0; i < n; i += 2) {
const resp_object *k = &o->u.arr.elem[i];
- const char *s = (k->type == RESPT_BULK || k->type == RESPT_SIMPLE) ? k->u.s : NULL;
- if (s && strcmp(s, key) == 0 && i + 1 < n)
- return (resp_object *)&o->u.arr.elem[i + 1];
+ const char *s = (k->type == RESPT_BULK || k->type == RESPT_SIMPLE) ? k->u.s : NULL;
+ if (s && strcmp(s, key) == 0 && i + 1 < n) return (resp_object *)&o->u.arr.elem[i + 1];
}
return NULL;
}
@@ -281,8 +372,7 @@ resp_object *resp_map_get(const resp_object *o, const char *key) {
const char *resp_map_get_string(const resp_object *o, const char *key) {
resp_object *val = resp_map_get(o, key);
if (!val) return NULL;
- if (val->type == RESPT_BULK || val->type == RESPT_SIMPLE)
- return val->u.s;
+ if (val->type == RESPT_BULK || val->type == RESPT_SIMPLE) return val->u.s;
return NULL;
}
@@ -290,7 +380,7 @@ void resp_map_set(resp_object *o, const char *key, resp_object *value) {
if (!o || !key || o->type != RESPT_ARRAY) return;
for (size_t i = 0; i + 1 < o->u.arr.n; i += 2) {
const resp_object *k = &o->u.arr.elem[i];
- const char *s = (k->type == RESPT_BULK || k->type == RESPT_SIMPLE) ? k->u.s : NULL;
+ const char *s = (k->type == RESPT_BULK || k->type == RESPT_SIMPLE) ? k->u.s : NULL;
if (s && strcmp(s, key) == 0 && i + 1 < o->u.arr.n) {
resp_free(&o->u.arr.elem[i + 1]);
o->u.arr.elem[i + 1] = *value;
@@ -307,48 +397,50 @@ static int resp_append_object(char **buf, size_t *cap, size_t *len, const resp_o
size_t need = *len + 256;
if (o->type == RESPT_BULK || o->type == RESPT_SIMPLE || o->type == RESPT_ERROR) {
size_t slen = o->u.s ? strlen(o->u.s) : 0;
- need = *len + 32 + slen + 2;
+ need = *len + 32 + slen + 2;
} else if (o->type == RESPT_ARRAY) {
need = *len + 32;
- for (size_t i = 0; i < o->u.arr.n; i++)
- need += 64;
+ for (size_t i = 0; i < o->u.arr.n; i++) need += 64;
}
if (need > *cap) {
size_t newcap = need + 4096;
- char *n = realloc(*buf, newcap);
+ char *n = realloc(*buf, newcap);
if (!n) return -1;
*buf = n;
*cap = newcap;
}
switch (o->type) {
- case RESPT_SIMPLE: {
- const char *s = o->u.s ? o->u.s : "";
- *len += (size_t)snprintf(*buf + *len, *cap - *len, "+%s\r\n", s);
- break;
- }
- case RESPT_ERROR: {
- const char *s = o->u.s ? o->u.s : "";
- *len += (size_t)snprintf(*buf + *len, *cap - *len, "-%s\r\n", s);
- break;
- }
+ case RESPT_SIMPLE:
+ {
+ const char *s = o->u.s ? o->u.s : "";
+ *len += (size_t)snprintf(*buf + *len, *cap - *len, "+%s\r\n", s);
+ break;
+ }
+ case RESPT_ERROR:
+ {
+ const char *s = o->u.s ? o->u.s : "";
+ *len += (size_t)snprintf(*buf + *len, *cap - *len, "-%s\r\n", s);
+ break;
+ }
case RESPT_INT:
*len += (size_t)snprintf(*buf + *len, *cap - *len, ":%lld\r\n", (long long)o->u.i);
break;
- case RESPT_BULK: {
- const char *s = o->u.s ? o->u.s : "";
- size_t slen = strlen(s);
- *len += (size_t)snprintf(*buf + *len, *cap - *len, "$%zu\r\n%s\r\n", slen, s);
- break;
- }
- case RESPT_ARRAY: {
- size_t n = o->u.arr.n;
- *len += (size_t)snprintf(*buf + *len, *cap - *len, "*%zu\r\n", n);
- for (size_t i = 0; i < n; i++) {
- if (resp_append_object(buf, cap, len, &o->u.arr.elem[i]) != 0)
- return -1;
+ case RESPT_BULK:
+ {
+ const char *s = o->u.s ? o->u.s : "";
+ size_t slen = strlen(s);
+ *len += (size_t)snprintf(*buf + *len, *cap - *len, "$%zu\r\n%s\r\n", slen, s);
+ break;
+ }
+ case RESPT_ARRAY:
+ {
+ size_t n = o->u.arr.n;
+ *len += (size_t)snprintf(*buf + *len, *cap - *len, "*%zu\r\n", n);
+ for (size_t i = 0; i < n; i++) {
+ if (resp_append_object(buf, cap, len, &o->u.arr.elem[i]) != 0) return -1;
+ }
+ break;
}
- break;
- }
default:
return -1;
}
@@ -358,10 +450,13 @@ static int resp_append_object(char **buf, size_t *cap, size_t *len, const resp_o
int resp_encode_array(int argc, const resp_object *const *argv, char **out_buf, size_t *out_len) {
size_t cap = 64;
size_t len = 0;
- char *buf = malloc(cap);
+ char *buf = malloc(cap);
if (!buf) return -1;
len += (size_t)snprintf(buf + len, cap - len, "*%d\r\n", argc);
- if (len >= cap) { free(buf); return -1; }
+ if (len >= cap) {
+ free(buf);
+ return -1;
+ }
for (int i = 0; i < argc; i++) {
if (resp_append_object(&buf, &cap, &len, argv[i]) != 0) {
free(buf);
@@ -376,7 +471,7 @@ int resp_encode_array(int argc, const resp_object *const *argv, char **out_buf,
int resp_serialize(const resp_object *o, char **out_buf, size_t *out_len) {
size_t cap = 64;
size_t len = 0;
- char *buf = malloc(cap);
+ char *buf = malloc(cap);
if (!buf) return -1;
if (resp_append_object(&buf, &cap, &len, o) != 0) {
free(buf);
@@ -390,8 +485,8 @@ int resp_serialize(const resp_object *o, char **out_buf, size_t *out_len) {
resp_object *resp_array_init(void) {
resp_object *o = calloc(1, sizeof(resp_object));
if (!o) return NULL;
- o->type = RESPT_ARRAY;
- o->u.arr.n = 0;
+ o->type = RESPT_ARRAY;
+ o->u.arr.n = 0;
o->u.arr.elem = NULL;
return o;
}
@@ -400,16 +495,16 @@ resp_object *resp_simple_init(const char *value) {
resp_object *o = calloc(1, sizeof(resp_object));
if (!o) return NULL;
o->type = RESPT_SIMPLE;
- o->u.s = value ? strdup(value) : NULL;
+ o->u.s = value ? strdup(value) : NULL;
return o;
}
int resp_array_append_obj(resp_object *destination, resp_object *value) {
if (!destination || destination->type != RESPT_ARRAY || !value) return -1;
- size_t n = destination->u.arr.n;
+ size_t n = destination->u.arr.n;
resp_object *new_elem = realloc(destination->u.arr.elem, (n + 1) * sizeof(resp_object));
if (!new_elem) return -1;
- destination->u.arr.elem = new_elem;
+ destination->u.arr.elem = new_elem;
destination->u.arr.elem[n] = *value;
destination->u.arr.n++;
free(value);
@@ -420,8 +515,11 @@ resp_object *resp_error_init(const char *value) {
resp_object *o = calloc(1, sizeof(resp_object));
if (!o) return NULL;
o->type = RESPT_ERROR;
- o->u.s = strdup(value ? value : "");
- if (!o->u.s) { free(o); return NULL; }
+ o->u.s = strdup(value ? value : "");
+ if (!o->u.s) {
+ free(o);
+ return NULL;
+ }
return o;
}
@@ -429,9 +527,16 @@ int resp_array_append_simple(resp_object *destination, const char *str) {
resp_object *o = calloc(1, sizeof(resp_object));
if (!o) return -1;
o->type = RESPT_SIMPLE;
- o->u.s = strdup(str ? str : "");
- if (!o->u.s) { free(o); return -1; }
- if (resp_array_append_obj(destination, o) != 0) { free(o->u.s); free(o); return -1; }
+ o->u.s = strdup(str ? str : "");
+ if (!o->u.s) {
+ free(o);
+ return -1;
+ }
+ if (resp_array_append_obj(destination, o) != 0) {
+ free(o->u.s);
+ free(o);
+ return -1;
+ }
return 0;
}
@@ -439,9 +544,16 @@ int resp_array_append_error(resp_object *destination, const char *str) {
resp_object *o = calloc(1, sizeof(resp_object));
if (!o) return -1;
o->type = RESPT_ERROR;
- o->u.s = strdup(str ? str : "");
- if (!o->u.s) { free(o); return -1; }
- if (resp_array_append_obj(destination, o) != 0) { free(o->u.s); free(o); return -1; }
+ o->u.s = strdup(str ? str : "");
+ if (!o->u.s) {
+ free(o);
+ return -1;
+ }
+ if (resp_array_append_obj(destination, o) != 0) {
+ free(o->u.s);
+ free(o);
+ return -1;
+ }
return 0;
}
@@ -449,9 +561,16 @@ int resp_array_append_bulk(resp_object *destination, const char *str) {
resp_object *o = calloc(1, sizeof(resp_object));
if (!o) return -1;
o->type = RESPT_BULK;
- o->u.s = strdup(str ? str : "");
- if (!o->u.s) { free(o); return -1; }
- if (resp_array_append_obj(destination, o) != 0) { free(o->u.s); free(o); return -1; }
+ o->u.s = strdup(str ? str : "");
+ if (!o->u.s) {
+ free(o);
+ return -1;
+ }
+ if (resp_array_append_obj(destination, o) != 0) {
+ free(o->u.s);
+ free(o);
+ return -1;
+ }
return 0;
}
@@ -459,6 +578,6 @@ int resp_array_append_int(resp_object *destination, long long i) {
resp_object *o = malloc(sizeof(resp_object));
if (!o) return -1;
o->type = RESPT_INT;
- o->u.i = i;
+ o->u.i = i;
return resp_array_append_obj(destination, o);
}
diff --git a/src/common/resp.h b/src/common/resp.h
@@ -3,19 +3,22 @@
#include <stddef.h>
-#define RESPT_SIMPLE 0
-#define RESPT_ERROR 1
-#define RESPT_BULK 2
-#define RESPT_INT 3
-#define RESPT_ARRAY 4
+#define RESPT_SIMPLE 0
+#define RESPT_ERROR 1
+#define RESPT_BULK 2
+#define RESPT_INT 3
+#define RESPT_ARRAY 4
typedef struct resp_object resp_object;
struct resp_object {
int type;
union {
- char *s;
+ char *s;
long long i;
- struct { resp_object *elem; size_t n; } arr;
+ struct {
+ resp_object *elem;
+ size_t n;
+ } arr;
} u;
};
@@ -50,7 +53,8 @@ resp_object *resp_array_init(void);
/* Returns new array object: caller owns the result, must call resp_free() */
resp_object *resp_simple_init(const char *value);
-/* Returns new simple string object: caller owns the result, must call resp_free() */
+/* Returns new simple string object: caller owns the result, must call
+ * resp_free() */
resp_object *resp_error_init(const char *value);
/* Returns new error object: caller owns the result, must call resp_free() */
diff --git a/src/common/scheduler.c b/src/common/scheduler.c
@@ -1,27 +1,27 @@
+#include "common/scheduler.h"
+
#include <stdlib.h>
#include <sys/select.h>
#include <sys/time.h>
-#include "common/scheduler.h"
-
#ifndef NULL
-#define NULL ((void*)0)
+#define NULL ((void *)0)
#endif
-pt_task_t *pt_first = NULL;
-fd_set g_select_result;
+pt_task_t *pt_first = NULL;
+fd_set g_select_result;
static fd_set g_want_fds;
int sched_create(pt_task_fn fn, void *udata) {
if (!fn) return 1;
pt_task_t *node = calloc(1, sizeof(pt_task_t));
- node->next = pt_first;
- node->func = fn;
- node->udata = udata;
- node->is_active = 1;
- pt_first = node;
-
+ node->next = pt_first;
+ node->func = fn;
+ node->udata = udata;
+ node->is_active = 1;
+ pt_first = node;
+
return 0;
}
@@ -73,9 +73,9 @@ int sched_main(void) {
if (!pt_first) return 0;
struct timeval tv;
- int maxfd;
+ int maxfd;
- for(;;) {
+ for (;;) {
maxfd = -1;
for (int fd = 0; fd < FD_SETSIZE; fd++) {
if (FD_ISSET(fd, &g_want_fds)) {
@@ -84,11 +84,11 @@ int sched_main(void) {
}
if (maxfd < 0) {
- tv.tv_sec = 0;
+ tv.tv_sec = 0;
tv.tv_usec = 100000;
select(0, NULL, NULL, NULL, &tv);
} else {
- tv.tv_sec = 0;
+ tv.tv_sec = 0;
tv.tv_usec = 100000;
select(maxfd + 1, &g_want_fds, NULL, NULL, &tv);
g_select_result = g_want_fds;
diff --git a/src/common/scheduler.h b/src/common/scheduler.h
@@ -14,10 +14,10 @@ typedef int (*pt_task_fn)(int64_t timestamp, struct pt_task *task);
typedef struct pt_task {
struct pt_task *next;
- pt_task_fn func;
- void *udata;
- char is_active;
- int maxfd;
+ pt_task_fn func;
+ void *udata;
+ char is_active;
+ int maxfd;
} pt_task_t;
int sched_create(pt_task_fn fn, void *udata);
@@ -26,4 +26,4 @@ int sched_main(void);
int sched_has_data(int *in_fds);
-#endif // UDPHOLE_SCHEDULER_H
+#endif // UDPHOLE_SCHEDULER_H
diff --git a/src/common/socket_util.c b/src/common/socket_util.c
@@ -1,19 +1,21 @@
#include "common/socket_util.h"
-#include "rxi/log.h"
+
+#include <arpa/inet.h>
+#include <errno.h>
#include <fcntl.h>
-#include <unistd.h>
-#include <string.h>
+#include <grp.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <errno.h>
-#include <sys/un.h>
#include <sys/stat.h>
-#include <pwd.h>
-#include <grp.h>
+#include <sys/un.h>
+#include <unistd.h>
+
+#include "rxi/log.h"
int set_socket_nonblocking(int fd, int nonblock) {
int flags = fcntl(fd, F_GETFL, 0);
@@ -27,7 +29,7 @@ int set_socket_nonblocking(int fd, int nonblock) {
int *tcp_listen(const char *addr, const char *default_host, const char *default_port) {
char host[256] = "";
- char port[32] = "";
+ char port[32] = "";
if (default_host && default_host[0]) {
snprintf(host, sizeof(host), "%s", default_host);
@@ -61,11 +63,14 @@ int *tcp_listen(const char *addr, const char *default_host, const char *default_
return NULL;
}
} else {
- int leading_colon = (addr[0] == ':');
- const char *p = leading_colon ? addr + 1 : addr;
- int is_port_only = 1;
+ int leading_colon = (addr[0] == ':');
+ const char *p = leading_colon ? addr + 1 : addr;
+ int is_port_only = 1;
for (const char *q = p; *q; q++) {
- if (*q < '0' || *q > '9') { is_port_only = 0; break; }
+ if (*q < '0' || *q > '9') {
+ is_port_only = 0;
+ break;
+ }
}
const char *colon = strrchr(addr, ':');
@@ -96,9 +101,9 @@ int *tcp_listen(const char *addr, const char *default_host, const char *default_
struct addrinfo hints, *res = NULL;
memset(&hints, 0, sizeof(hints));
- hints.ai_family = AF_UNSPEC;
+ hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
- hints.ai_flags = AI_PASSIVE;
+ hints.ai_flags = AI_PASSIVE;
if (getaddrinfo(host[0] ? host : NULL, port, &hints, &res) != 0 || !res) {
log_error("tcp_listen: getaddrinfo failed for %s:%s", host, port);
return NULL;
@@ -111,7 +116,7 @@ int *tcp_listen(const char *addr, const char *default_host, const char *default_
}
fds[0] = 0;
- int listen_all = (host[0] == '\0');
+ int listen_all = (host[0] == '\0');
struct addrinfo *p;
for (p = res; p; p = p->ai_next) {
@@ -154,7 +159,7 @@ int *tcp_listen(const char *addr, const char *default_host, const char *default_
int *udp_recv(const char *addr, const char *default_host, const char *default_port) {
char host[256] = "";
- char port[32] = "";
+ char port[32] = "";
if (default_host && default_host[0]) {
snprintf(host, sizeof(host), "%s", default_host);
@@ -188,11 +193,14 @@ int *udp_recv(const char *addr, const char *default_host, const char *default_po
return NULL;
}
} else {
- int leading_colon = (addr[0] == ':');
- const char *p = leading_colon ? addr + 1 : addr;
- int is_port_only = 1;
+ int leading_colon = (addr[0] == ':');
+ const char *p = leading_colon ? addr + 1 : addr;
+ int is_port_only = 1;
for (const char *q = p; *q; q++) {
- if (*q < '0' || *q > '9') { is_port_only = 0; break; }
+ if (*q < '0' || *q > '9') {
+ is_port_only = 0;
+ break;
+ }
}
const char *colon = strrchr(addr, ':');
@@ -223,9 +231,9 @@ int *udp_recv(const char *addr, const char *default_host, const char *default_po
struct addrinfo hints, *res = NULL;
memset(&hints, 0, sizeof(hints));
- hints.ai_family = AF_UNSPEC;
+ hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM;
- hints.ai_flags = AI_PASSIVE;
+ hints.ai_flags = AI_PASSIVE;
if (getaddrinfo(host[0] ? host : NULL, port, &hints, &res) != 0 || !res) {
log_error("udp_recv: getaddrinfo failed for %s:%s", host, port);
return NULL;
@@ -238,7 +246,7 @@ int *udp_recv(const char *addr, const char *default_host, const char *default_po
}
fds[0] = 0;
- int listen_all = (host[0] == '\0');
+ int listen_all = (host[0] == '\0');
struct addrinfo *p;
for (p = res; p; p = p->ai_next) {
@@ -339,8 +347,8 @@ int *unix_listen(const char *path, int sock_type, const char *owner) {
}
if (owner && owner[0]) {
- uid_t uid = -1;
- gid_t gid = -1;
+ uid_t uid = -1;
+ gid_t gid = -1;
char *owner_copy = strdup(owner);
if (owner_copy) {
char *colon = strchr(owner_copy, ':');
@@ -350,7 +358,7 @@ int *unix_listen(const char *path, int sock_type, const char *owner) {
if (colon[0]) {
struct passwd *pw = getpwnam(owner_copy);
if (pw) {
- uid = pw->pw_uid;
+ uid = pw->pw_uid;
struct group *gr = getgrnam(colon);
if (gr) {
gid = gr->gr_gid;
diff --git a/src/common/socket_util.h b/src/common/socket_util.h
@@ -1,23 +1,23 @@
#ifndef UDPHOLE_SOCKET_UTIL_H
#define UDPHOLE_SOCKET_UTIL_H
-/* Set socket blocking (0) or non-blocking (1). Returns 0 on success, -1 on error. */
+/* Set socket blocking (0) or non-blocking (1). Returns 0 on success, -1 on
+ * error. */
int set_socket_nonblocking(int fd, int nonblock);
/* Create listening sockets. Supports dual-stack when host is empty.
- * addr can be "port", "host:port", or "[ipv6]:port". Missing host uses default_host,
- * missing port uses default_port.
- * Returns int array: index 0 = count, index 1+ = socket fds. Caller must free.
- * On error returns NULL. */
+ * addr can be "port", "host:port", or "[ipv6]:port". Missing host uses
+ * default_host, missing port uses default_port. Returns int array: index 0 =
+ * count, index 1+ = socket fds. Caller must free. On error returns NULL. */
int *tcp_listen(const char *addr, const char *default_host, const char *default_port);
/* Create UDP receiving sockets. Same semantics as tcp_listen(). */
int *udp_recv(const char *addr, const char *default_host, const char *default_port);
-/* Create Unix domain socket. path is the socket path, sock_type is SOCK_DGRAM or SOCK_STREAM.
- * owner is optional and can be "user" or "user:group" to set socket ownership.
- * Returns int array: index 0 = count, index 1 = socket fd. Caller must free.
- * On error returns NULL. */
+/* Create Unix domain socket. path is the socket path, sock_type is SOCK_DGRAM
+ * or SOCK_STREAM. owner is optional and can be "user" or "user:group" to set
+ * socket ownership. Returns int array: index 0 = count, index 1 = socket fd.
+ * Caller must free. On error returns NULL. */
int *unix_listen(const char *path, int sock_type, const char *owner);
#endif
diff --git a/src/domain/cluster/cluster.c b/src/domain/cluster/cluster.c
@@ -1,13 +1,14 @@
+#include "cluster.h"
+
+#include <math.h>
+#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <stdio.h>
-#include <math.h>
-#include "rxi/log.h"
#include "common/resp.h"
#include "common/scheduler.h"
#include "domain/config.h"
-#include "cluster.h"
+#include "rxi/log.h"
cluster_state_t *cluster_state = NULL;
@@ -21,12 +22,12 @@ static int is_session_not_found(resp_object *resp) {
}
static resp_object *cluster_forward_to_nodes(const char *cmd_str) {
- size_t available_count = 0;
- cluster_node_t **available = cluster_nodes_get_available(cluster_state->nodes, &available_count);
+ size_t available_count = 0;
+ cluster_node_t **available = cluster_nodes_get_available(cluster_state->nodes, &available_count);
if (!available || available_count == 0) {
free(available);
- return resp_error_init("ERR no available nodes");
+ return resp_error_init("ERR no available nodes");
}
for (size_t i = 0; i < available_count; i++) {
@@ -64,7 +65,7 @@ void cluster_init(void) {
cluster_shutdown();
}
- cluster_state = calloc(1, sizeof(cluster_state_t));
+ cluster_state = calloc(1, sizeof(cluster_state_t));
cluster_state->nodes = cluster_nodes_create();
if (!domain_cfg) return;
@@ -79,22 +80,22 @@ void cluster_init(void) {
for (size_t i = 0; i < cluster_nodes->u.arr.n; i++) {
resp_object *elem = &cluster_nodes->u.arr.elem[i];
if (elem->type != RESPT_BULK || !elem->u.s) continue;
-
+
const char *node_name = elem->u.s;
-
+
char node_section[256];
snprintf(node_section, sizeof(node_section), "cluster:%s", node_name);
resp_object *node_sec = resp_map_get(domain_cfg, node_section);
-
- const char *address = node_sec ? resp_map_get_string(node_sec, "address") : NULL;
+
+ const char *address = node_sec ? resp_map_get_string(node_sec, "address") : NULL;
const char *username = node_sec ? resp_map_get_string(node_sec, "username") : NULL;
const char *password = node_sec ? resp_map_get_string(node_sec, "password") : NULL;
-
+
if (!address) {
log_error("cluster: node '%s' has no address configured", node_name);
continue;
}
-
+
cluster_node_t *node = calloc(1, sizeof(cluster_node_t));
if (cluster_node_init(node, node_name, address, username, password) == 0) {
cluster_nodes_add(cluster_state->nodes, node);
@@ -124,7 +125,7 @@ void cluster_shutdown(void) {
}
static char *serialize_args(resp_object *args) {
- char *cmd_str = NULL;
+ char *cmd_str = NULL;
size_t cmd_len = 0;
resp_serialize(args, &cmd_str, &cmd_len);
return cmd_str;
@@ -141,20 +142,20 @@ resp_object *cluster_session_create(const char *cmd, resp_object *args) {
return resp_error_init("ERR failed to serialize command");
}
- cluster_node_t *selected_node = NULL;
- double selected_ratio = -1.0;
- resp_object *resp = NULL;
+ cluster_node_t *selected_node = NULL;
+ double selected_ratio = -1.0;
+ resp_object *resp = NULL;
for (int attempt = 0; attempt < 10; attempt++) {
- size_t available_count = 0;
- cluster_node_t **available = cluster_nodes_get_available(cluster_state->nodes, &available_count);
+ size_t available_count = 0;
+ cluster_node_t **available = cluster_nodes_get_available(cluster_state->nodes, &available_count);
if (!available || available_count == 0) {
free(available);
break;
}
- selected_node = NULL;
+ selected_node = NULL;
selected_ratio = -1.0;
for (size_t i = 0; i < available_count; i++) {
@@ -168,7 +169,8 @@ resp_object *cluster_session_create(const char *cmd, resp_object *args) {
size_t node_session_count = 0;
if (count_str) {
resp_object *count_resp = NULL;
- if (cluster_node_send_command(node, count_str, &count_resp) == 0 && count_resp && count_resp->type == RESPT_INT) {
+ if (cluster_node_send_command(node, count_str, &count_resp) == 0 && count_resp &&
+ count_resp->type == RESPT_INT) {
node_session_count = (size_t)count_resp->u.i;
}
if (count_resp) resp_free(count_resp);
@@ -177,7 +179,7 @@ resp_object *cluster_session_create(const char *cmd, resp_object *args) {
double ratio = (double)node_session_count / (double)node->weight;
if (selected_node == NULL || ratio < selected_ratio) {
- selected_node = node;
+ selected_node = node;
selected_ratio = ratio;
}
}
@@ -213,8 +215,8 @@ resp_object *cluster_session_list(const char *cmd, resp_object *args) {
return resp_error_init("ERR cluster not initialized");
}
- size_t available_count = 0;
- cluster_node_t **available = cluster_nodes_get_available(cluster_state->nodes, &available_count);
+ size_t available_count = 0;
+ cluster_node_t **available = cluster_nodes_get_available(cluster_state->nodes, &available_count);
if (!available || available_count == 0) {
free(available);
@@ -256,12 +258,12 @@ resp_object *cluster_session_info(const char *cmd, resp_object *args) {
return resp_error_init("ERR cluster not initialized");
}
- size_t available_count = 0;
- cluster_node_t **available = cluster_nodes_get_available(cluster_state->nodes, &available_count);
+ size_t available_count = 0;
+ cluster_node_t **available = cluster_nodes_get_available(cluster_state->nodes, &available_count);
if (!available || available_count == 0) {
free(available);
- return resp_error_init("ERR no available nodes");
+ return resp_error_init("ERR no available nodes");
}
resp_object *cmd_args = resp_array_init();
@@ -447,15 +449,15 @@ resp_object *cluster_session_count(const char *cmd, resp_object *args) {
return resp_error_init("ERR cluster not initialized");
}
- size_t available_count = 0;
- cluster_node_t **available = cluster_nodes_get_available(cluster_state->nodes, &available_count);
+ size_t available_count = 0;
+ cluster_node_t **available = cluster_nodes_get_available(cluster_state->nodes, &available_count);
if (!available || available_count == 0) {
free(available);
resp_object *res = malloc(sizeof(resp_object));
if (!res) return NULL;
res->type = RESPT_INT;
- res->u.i = 0;
+ res->u.i = 0;
return res;
}
@@ -484,7 +486,7 @@ resp_object *cluster_session_count(const char *cmd, resp_object *args) {
resp_object *res = malloc(sizeof(resp_object));
if (!res) return NULL;
res->type = RESPT_INT;
- res->u.i = (long long)total_count;
+ res->u.i = (long long)total_count;
return res;
}
@@ -498,7 +500,7 @@ resp_object *cluster_system_load(const char *cmd, resp_object *args) {
}
resp_object *res = resp_array_init();
- char buf[64];
+ char buf[64];
resp_array_append_bulk(res, "1min");
snprintf(buf, sizeof(buf), "%.2f", loadavg[0]);
diff --git a/src/domain/cluster/cluster.h b/src/domain/cluster/cluster.h
@@ -6,7 +6,7 @@
typedef struct {
cluster_nodes_t *nodes;
- int initialized;
+ int initialized;
} cluster_state_t;
extern cluster_state_t *cluster_state;
diff --git a/src/domain/cluster/node.c b/src/domain/cluster/node.c
@@ -1,29 +1,30 @@
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include <unistd.h>
+#include "node.h"
+
+#include <arpa/inet.h>
#include <errno.h>
#include <fcntl.h>
-#include <sys/socket.h>
-#include <sys/un.h>
+#include <netdb.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
-#include <arpa/inet.h>
-#include <netdb.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
-#include "rxi/log.h"
#include "common/resp.h"
#include "common/socket_util.h"
-#include "node.h"
+#include "rxi/log.h"
-#define QUERY_TIMEOUT_MS 500
+#define QUERY_TIMEOUT_MS 500
#define HEALTHCHECK_INTERVAL_MS 5000
static int parse_address(const char *address, char **host, int *port, char **unix_path) {
if (!address) return -1;
if (strncmp(address, "tcp://", 6) == 0) {
- const char *hp = address + 6;
+ const char *hp = address + 6;
const char *colon = strchr(hp, ':');
if (!colon) {
log_error("cluster: invalid tcp address '%s' (missing port)", address);
@@ -31,7 +32,7 @@ static int parse_address(const char *address, char **host, int *port, char **uni
}
size_t host_len = colon - hp;
- *host = malloc(host_len + 1);
+ *host = malloc(host_len + 1);
if (!*host) return -1;
memcpy(*host, hp, host_len);
(*host)[host_len] = '\0';
@@ -48,8 +49,8 @@ static int parse_address(const char *address, char **host, int *port, char **uni
} else if (strncmp(address, "unix://", 7) == 0) {
*unix_path = strdup(address + 7);
- *host = NULL;
- *port = 0;
+ *host = NULL;
+ *port = 0;
return 0;
}
@@ -57,11 +58,12 @@ static int parse_address(const char *address, char **host, int *port, char **uni
return -1;
}
-int cluster_node_init(cluster_node_t *node, const char *name, const char *address, const char *username, const char *password) {
+int cluster_node_init(cluster_node_t *node, const char *name, const char *address, const char *username,
+ const char *password) {
memset(node, 0, sizeof(*node));
- node->name = strdup(name);
- node->address = address ? strdup(address) : NULL;
+ node->name = strdup(name);
+ node->address = address ? strdup(address) : NULL;
node->username = username ? strdup(username) : NULL;
node->password = password ? strdup(password) : NULL;
@@ -74,11 +76,11 @@ int cluster_node_init(cluster_node_t *node, const char *name, const char *addres
return -1;
}
- node->fd = -1;
- node->available = 0;
- node->last_ping = 0;
+ node->fd = -1;
+ node->available = 0;
+ node->last_ping = 0;
node->last_check = 0;
- node->weight = 1;
+ node->weight = 1;
return 0;
}
@@ -96,10 +98,10 @@ void cluster_node_free(cluster_node_t *node) {
static int connect_tcp(const char *host, int port) {
struct addrinfo hints, *res, *res0;
- int sockfd, error;
+ int sockfd, error;
memset(&hints, 0, sizeof(hints));
- hints.ai_family = AF_UNSPEC;
+ hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = 0;
@@ -135,7 +137,7 @@ static int connect_tcp(const char *host, int port) {
static int connect_unix(const char *path) {
struct sockaddr_un addr;
- int sockfd;
+ int sockfd;
if (strlen(path) >= sizeof(addr.sun_path)) {
log_error("cluster: unix socket path too long: %s", path);
@@ -178,9 +180,9 @@ int cluster_node_connect(cluster_node_t *node) {
log_info("cluster: connected to node '%s' at %s", node->name, node->address);
if (node->username && node->password) {
- char *cmd_str = NULL;
- size_t cmd_len = 0;
- resp_object *cmd = resp_array_init();
+ char *cmd_str = NULL;
+ size_t cmd_len = 0;
+ resp_object *cmd = resp_array_init();
resp_array_append_bulk(cmd, "auth");
resp_array_append_bulk(cmd, node->username);
resp_array_append_bulk(cmd, node->password);
@@ -215,8 +217,8 @@ void cluster_node_disconnect(cluster_node_t *node) {
}
static int send_resp_command(int fd, const char *cmd) {
- size_t cmd_len = strlen(cmd);
- ssize_t n = send(fd, cmd, cmd_len, 0);
+ size_t cmd_len = strlen(cmd);
+ ssize_t n = send(fd, cmd, cmd_len, 0);
return (n == (ssize_t)cmd_len) ? 0 : -1;
}
@@ -263,9 +265,9 @@ int cluster_node_healthcheck_pt(int64_t timestamp, struct pt_task *task) {
}
}
- char *cmd_str = NULL;
- size_t cmd_len = 0;
- resp_object *cmd = resp_array_init();
+ char *cmd_str = NULL;
+ size_t cmd_len = 0;
+ resp_object *cmd = resp_array_init();
resp_array_append_bulk(cmd, "ping");
resp_serialize(cmd, &cmd_str, &cmd_len);
resp_free(cmd);
@@ -319,10 +321,9 @@ void cluster_nodes_free(cluster_nodes_t *cnodes) {
}
int cluster_nodes_add(cluster_nodes_t *cnodes, cluster_node_t *node) {
- cluster_node_t **new_nodes = realloc(cnodes->nodes,
- sizeof(cluster_node_t *) * (cnodes->nodes_count + 1));
+ cluster_node_t **new_nodes = realloc(cnodes->nodes, sizeof(cluster_node_t *) * (cnodes->nodes_count + 1));
if (!new_nodes) return -1;
- cnodes->nodes = new_nodes;
+ cnodes->nodes = new_nodes;
cnodes->nodes[cnodes->nodes_count++] = node;
return 0;
}
diff --git a/src/domain/cluster/node.h b/src/domain/cluster/node.h
@@ -2,6 +2,7 @@
#define UDPHOLE_CLUSTER_NODE_H
#include <stdint.h>
+
#include "common/resp.h"
#include "common/scheduler.h"
@@ -9,24 +10,25 @@ typedef struct cluster_node {
char *name;
char *address;
char *host;
- int port;
+ int port;
char *unix_path;
char *username;
char *password;
- int weight;
+ int weight;
- int fd;
- int available;
+ int fd;
+ int available;
int64_t last_ping;
int64_t last_check;
} cluster_node_t;
typedef struct {
cluster_node_t **nodes;
- size_t nodes_count;
+ size_t nodes_count;
} cluster_nodes_t;
-int cluster_node_init(cluster_node_t *node, const char *name, const char *address, const char *username, const char *password);
+int cluster_node_init(cluster_node_t *node, const char *name, const char *address, const char *username,
+ const char *password);
void cluster_node_free(cluster_node_t *node);
diff --git a/src/domain/config.c b/src/domain/config.c
@@ -1,8 +1,8 @@
+#include "domain/config.h"
+
+#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <stdio.h>
-
-#include "domain/config.h"
resp_object *domain_cfg = NULL;
diff --git a/src/domain/config.h b/src/domain/config.h
@@ -2,6 +2,7 @@
#define UDPHOLE_DOMAIN_CONFIG_H
#include <stdint.h>
+
#include "common/resp.h"
extern resp_object *domain_cfg;
diff --git a/src/domain/daemon/session.c b/src/domain/daemon/session.c
@@ -1,43 +1,44 @@
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <unistd.h>
+#include "session.h"
+
+#include <arpa/inet.h>
#include <errno.h>
#include <fcntl.h>
-#include <time.h>
+#include <netinet/in.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
#include <sys/socket.h>
-#include <sys/un.h>
#include <sys/stat.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
+#include <sys/un.h>
+#include <time.h>
+#include <unistd.h>
-#include "rxi/log.h"
+#include "common/resp.h"
#include "common/scheduler.h"
-#include "domain/config.h"
#include "common/socket_util.h"
-#include "common/resp.h"
+#include "domain/config.h"
+#include "rxi/log.h"
#include "tidwall/hashmap.h"
-#include "session.h"
static resp_object *get_udphole_cfg(void) {
return domain_cfg ? resp_map_get(domain_cfg, "udphole") : NULL;
}
-#define SESSION_HASH_SIZE 256
-#define BUFFER_SIZE 4096
+#define SESSION_HASH_SIZE 256
+#define BUFFER_SIZE 4096
#define DEFAULT_IDLE_EXPIRY 60
typedef struct socket {
- char *socket_id;
- int *fds;
- int local_port;
- int mode;
+ char *socket_id;
+ int *fds;
+ int local_port;
+ int mode;
struct sockaddr_storage remote_addr;
- socklen_t remote_addrlen;
- int learned_valid;
+ socklen_t remote_addrlen;
+ int learned_valid;
struct sockaddr_storage learned_addr;
- socklen_t learned_addrlen;
+ socklen_t learned_addrlen;
} socket_t;
typedef struct forward {
@@ -46,22 +47,22 @@ typedef struct forward {
} forward_t;
typedef struct session {
- char *session_id;
- time_t idle_expiry;
- time_t created;
- time_t last_activity;
- socket_t **sockets;
- size_t sockets_count;
- forward_t *forwards;
- size_t forwards_count;
- int marked_for_deletion;
- int *ready_fds;
- int *all_fds;
+ char *session_id;
+ time_t idle_expiry;
+ time_t created;
+ time_t last_activity;
+ socket_t **sockets;
+ size_t sockets_count;
+ forward_t *forwards;
+ size_t forwards_count;
+ int marked_for_deletion;
+ int *ready_fds;
+ int *all_fds;
struct pt_task *task;
} session_t;
-static session_t **sessions = NULL;
-static size_t sessions_count = 0;
+static session_t **sessions = NULL;
+static size_t sessions_count = 0;
static session_t *find_session(const char *session_id) {
for (size_t i = 0; i < sessions_count; i++) {
@@ -86,11 +87,11 @@ static int alloc_port(void) {
resp_object *udphole = get_udphole_cfg();
if (!udphole) return 0;
const char *ports_str = resp_map_get_string(udphole, "ports");
- int port_low = 7000, port_high = 7999, port_cur = 7000;
+ int port_low = 7000, port_high = 7999, port_cur = 7000;
if (ports_str) sscanf(ports_str, "%d-%d", &port_low, &port_high);
const char *port_cur_str = resp_map_get_string(udphole, "_port_cur");
if (port_cur_str) port_cur = atoi(port_cur_str);
-
+
for (int i = 0; i < port_high - port_low; i++) {
int port = port_cur + i;
if (port > port_high) port = port_low;
@@ -99,9 +100,9 @@ static int alloc_port(void) {
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
- addr.sin_family = AF_INET;
+ addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
- addr.sin_port = htons(port);
+ addr.sin_port = htons(port);
int udp_fd = socket(AF_INET, SOCK_DGRAM, 0);
if (udp_fd < 0) continue;
@@ -120,16 +121,16 @@ static int parse_ip_addr(const char *ip_str, int port, struct sockaddr_storage *
struct sockaddr_in *addr4 = (struct sockaddr_in *)addr;
if (inet_pton(AF_INET, ip_str, &addr4->sin_addr) == 1) {
addr4->sin_family = AF_INET;
- addr4->sin_port = htons(port);
- *addrlen = sizeof(*addr4);
+ addr4->sin_port = htons(port);
+ *addrlen = sizeof(*addr4);
return 0;
}
struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)addr;
if (inet_pton(AF_INET6, ip_str, &addr6->sin6_addr) == 1) {
addr6->sin6_family = AF_INET6;
- addr6->sin6_port = htons(port);
- *addrlen = sizeof(*addr6);
+ addr6->sin6_port = htons(port);
+ *addrlen = sizeof(*addr6);
return 0;
}
@@ -192,12 +193,12 @@ static session_t *create_session(const char *session_id, int idle_expiry) {
session_t *s = calloc(1, sizeof(*s));
if (!s) return NULL;
- s->session_id = strdup(session_id);
- s->created = time(NULL);
+ s->session_id = strdup(session_id);
+ s->created = time(NULL);
s->last_activity = s->created;
- s->idle_expiry = idle_expiry > 0 ? idle_expiry : DEFAULT_IDLE_EXPIRY;
+ s->idle_expiry = idle_expiry > 0 ? idle_expiry : DEFAULT_IDLE_EXPIRY;
- sessions = realloc(sessions, sizeof(session_t *) * (sessions_count + 1));
+ sessions = realloc(sessions, sizeof(session_t *) * (sessions_count + 1));
sessions[sessions_count++] = s;
return s;
@@ -211,8 +212,8 @@ static void cleanup_expired_sessions(void) {
session_t *s = sessions[i];
if (!s) continue;
if (now - s->last_activity > s->idle_expiry) {
- log_debug("udphole: session %s expired (idle %ld > expiry %ld)",
- s->session_id, (long)(now - s->last_activity), (long)s->idle_expiry);
+ log_debug("udphole: session %s expired (idle %ld > expiry %ld)", s->session_id, (long)(now - s->last_activity),
+ (long)s->idle_expiry);
destroy_session(s);
}
}
@@ -220,8 +221,7 @@ static void cleanup_expired_sessions(void) {
static int add_forward(session_t *s, const char *src_id, const char *dst_id) {
for (size_t i = 0; i < s->forwards_count; i++) {
- if (strcmp(s->forwards[i].src_socket_id, src_id) == 0 &&
- strcmp(s->forwards[i].dst_socket_id, dst_id) == 0) {
+ if (strcmp(s->forwards[i].src_socket_id, src_id) == 0 && strcmp(s->forwards[i].dst_socket_id, dst_id) == 0) {
return 0;
}
}
@@ -239,8 +239,7 @@ static int add_forward(session_t *s, const char *src_id, const char *dst_id) {
static int remove_forward(session_t *s, const char *src_id, const char *dst_id) {
for (size_t i = 0; i < s->forwards_count; i++) {
- if (strcmp(s->forwards[i].src_socket_id, src_id) == 0 &&
- strcmp(s->forwards[i].dst_socket_id, dst_id) == 0) {
+ if (strcmp(s->forwards[i].src_socket_id, src_id) == 0 && strcmp(s->forwards[i].dst_socket_id, dst_id) == 0) {
free(s->forwards[i].src_socket_id);
free(s->forwards[i].dst_socket_id);
for (size_t j = i; j < s->forwards_count - 1; j++) {
@@ -278,22 +277,20 @@ static socket_t *create_listen_socket(session_t *sess, const char *socket_id) {
return NULL;
}
- sock->socket_id = strdup(socket_id);
- sock->fds = fds;
- sock->local_port = port;
- sock->mode = 0;
+ sock->socket_id = strdup(socket_id);
+ sock->fds = fds;
+ sock->local_port = port;
+ sock->mode = 0;
sock->learned_valid = 0;
- sess->sockets = realloc(sess->sockets, sizeof(socket_t *) * (sess->sockets_count + 1));
+ sess->sockets = realloc(sess->sockets, sizeof(socket_t *) * (sess->sockets_count + 1));
sess->sockets[sess->sockets_count++] = sock;
- log_debug("udphole: created listen socket %s in session %s on port %d",
- socket_id, sess->session_id, port);
+ log_debug("udphole: created listen socket %s in session %s on port %d", socket_id, sess->session_id, port);
return sock;
}
-static socket_t *create_connect_socket(session_t *sess, const char *socket_id,
- const char *ip, int port) {
+static socket_t *create_connect_socket(session_t *sess, const char *socket_id, const char *ip, int port) {
socket_t *existing = find_socket(sess, socket_id);
if (existing) return existing;
@@ -313,7 +310,7 @@ static socket_t *create_connect_socket(session_t *sess, const char *socket_id,
}
struct sockaddr_storage remote_addr;
- socklen_t remote_addrlen;
+ socklen_t remote_addrlen;
if (parse_ip_addr(ip, port, &remote_addr, &remote_addrlen) != 0) {
log_error("udphole: invalid remote address %s:%d", ip, port);
free(fds);
@@ -326,19 +323,19 @@ static socket_t *create_connect_socket(session_t *sess, const char *socket_id,
return NULL;
}
- sock->socket_id = strdup(socket_id);
- sock->fds = fds;
- sock->local_port = local_port;
- sock->mode = 1;
- sock->remote_addr = remote_addr;
+ sock->socket_id = strdup(socket_id);
+ sock->fds = fds;
+ sock->local_port = local_port;
+ sock->mode = 1;
+ sock->remote_addr = remote_addr;
sock->remote_addrlen = remote_addrlen;
- sock->learned_valid = 0;
+ sock->learned_valid = 0;
- sess->sockets = realloc(sess->sockets, sizeof(socket_t *) * (sess->sockets_count + 1));
+ sess->sockets = realloc(sess->sockets, sizeof(socket_t *) * (sess->sockets_count + 1));
sess->sockets[sess->sockets_count++] = sock;
- log_debug("udphole: created connect socket %s in session %s on port %d -> %s:%d",
- socket_id, sess->session_id, local_port, ip, port);
+ log_debug("udphole: created connect socket %s in session %s on port %d -> %s:%d", socket_id, sess->session_id,
+ local_port, ip, port);
return sock;
}
@@ -354,7 +351,7 @@ static int destroy_socket(session_t *sess, const char *socket_id) {
}
free_socket(sock);
- for (size_t i = 0; i < sess->forwards_count; ) {
+ for (size_t i = 0; i < sess->forwards_count;) {
if (strcmp(sess->forwards[i].src_socket_id, socket_id) == 0 ||
strcmp(sess->forwards[i].dst_socket_id, socket_id) == 0) {
free(sess->forwards[i].src_socket_id);
@@ -420,21 +417,19 @@ int session_pt(int64_t timestamp, struct pt_task *task) {
return SCHED_RUNNING;
}
- char buffer[BUFFER_SIZE];
+ char buffer[BUFFER_SIZE];
socket_t *src_sock = find_socket_by_fd(s, ready_fd);
if (!src_sock) {
return SCHED_RUNNING;
}
struct sockaddr_storage from_addr;
- socklen_t from_len = sizeof(from_addr);
- ssize_t n = recvfrom(ready_fd, buffer, sizeof(buffer) - 1, 0,
- (struct sockaddr *)&from_addr, &from_len);
+ socklen_t from_len = sizeof(from_addr);
+ ssize_t n = recvfrom(ready_fd, buffer, sizeof(buffer) - 1, 0, (struct sockaddr *)&from_addr, &from_len);
if (n <= 0) {
if (errno != EAGAIN && errno != EWOULDBLOCK) {
- log_warn("udphole: recvfrom error on socket %s: %s",
- src_sock->socket_id, strerror(errno));
+ log_warn("udphole: recvfrom error on socket %s: %s", src_sock->socket_id, strerror(errno));
}
return SCHED_RUNNING;
}
@@ -442,9 +437,9 @@ int session_pt(int64_t timestamp, struct pt_task *task) {
s->last_activity = time(NULL);
if (src_sock->mode == 0 && !src_sock->learned_valid) {
- src_sock->learned_addr = from_addr;
+ src_sock->learned_addr = from_addr;
src_sock->learned_addrlen = from_len;
- src_sock->learned_valid = 1;
+ src_sock->learned_valid = 1;
log_debug("udphole: socket %s learned remote address", src_sock->socket_id);
}
@@ -456,23 +451,22 @@ int session_pt(int64_t timestamp, struct pt_task *task) {
socket_t *dst_sock = find_socket(s, s->forwards[i].dst_socket_id);
if (!dst_sock || !dst_sock->fds || dst_sock->fds[0] == 0) continue;
- struct sockaddr *dest_addr = NULL;
- socklen_t dest_addrlen = 0;
+ struct sockaddr *dest_addr = NULL;
+ socklen_t dest_addrlen = 0;
if (dst_sock->mode == 1) {
- dest_addr = (struct sockaddr *)&dst_sock->remote_addr;
+ dest_addr = (struct sockaddr *)&dst_sock->remote_addr;
dest_addrlen = dst_sock->remote_addrlen;
} else if (dst_sock->learned_valid) {
- dest_addr = (struct sockaddr *)&dst_sock->learned_addr;
+ dest_addr = (struct sockaddr *)&dst_sock->learned_addr;
dest_addrlen = dst_sock->learned_addrlen;
}
if (dest_addr && dest_addrlen > 0) {
- int dst_fd = dst_sock->fds[1];
- ssize_t sent = sendto(dst_fd, buffer, n, 0, dest_addr, dest_addrlen);
+ int dst_fd = dst_sock->fds[1];
+ ssize_t sent = sendto(dst_fd, buffer, n, 0, dest_addr, dest_addrlen);
if (sent < 0) {
- log_warn("udphole: forward failed %s -> %s: %s",
- src_sock->socket_id, dst_sock->socket_id, strerror(errno));
+ log_warn("udphole: forward failed %s -> %s: %s", src_sock->socket_id, dst_sock->socket_id, strerror(errno));
}
}
}
@@ -654,7 +648,7 @@ resp_object *domain_socket_create_listen(const char *cmd, resp_object *args) {
}
const char *session_id = NULL;
- const char *socket_id = NULL;
+ const char *socket_id = NULL;
if (args->u.arr.elem[1].type == RESPT_BULK) {
session_id = args->u.arr.elem[1].u.s;
@@ -684,8 +678,8 @@ resp_object *domain_socket_create_listen(const char *cmd, resp_object *args) {
resp_object *res = resp_array_init();
resp_array_append_int(res, sock->local_port);
- resp_object *udphole = get_udphole_cfg();
- const char *advertise = udphole ? resp_map_get_string(udphole, "advertise") : NULL;
+ resp_object *udphole = get_udphole_cfg();
+ const char *advertise = udphole ? resp_map_get_string(udphole, "advertise") : NULL;
resp_array_append_bulk(res, advertise ? advertise : "");
return res;
}
@@ -699,9 +693,9 @@ resp_object *domain_socket_create_connect(const char *cmd, resp_object *args) {
}
const char *session_id = NULL;
- const char *socket_id = NULL;
- const char *ip = NULL;
- const char *port_str = NULL;
+ const char *socket_id = NULL;
+ const char *ip = NULL;
+ const char *port_str = NULL;
if (args->u.arr.elem[1].type == RESPT_BULK) {
session_id = args->u.arr.elem[1].u.s;
@@ -739,8 +733,8 @@ resp_object *domain_socket_create_connect(const char *cmd, resp_object *args) {
resp_object *res = resp_array_init();
resp_array_append_int(res, sock->local_port);
- resp_object *udphole = get_udphole_cfg();
- const char *advertise = udphole ? resp_map_get_string(udphole, "advertise") : NULL;
+ resp_object *udphole = get_udphole_cfg();
+ const char *advertise = udphole ? resp_map_get_string(udphole, "advertise") : NULL;
resp_array_append_bulk(res, advertise ? advertise : "");
return res;
}
@@ -754,7 +748,7 @@ resp_object *domain_socket_destroy(const char *cmd, resp_object *args) {
}
const char *session_id = NULL;
- const char *socket_id = NULL;
+ const char *socket_id = NULL;
if (args->u.arr.elem[1].type == RESPT_BULK) {
session_id = args->u.arr.elem[1].u.s;
@@ -826,7 +820,7 @@ resp_object *domain_forward_create(const char *cmd, resp_object *args) {
return err;
}
- const char *session_id = NULL;
+ const char *session_id = NULL;
const char *src_socket_id = NULL;
const char *dst_socket_id = NULL;
@@ -886,7 +880,7 @@ resp_object *domain_forward_destroy(const char *cmd, resp_object *args) {
return err;
}
- const char *session_id = NULL;
+ const char *session_id = NULL;
const char *src_socket_id = NULL;
const char *dst_socket_id = NULL;
@@ -934,7 +928,7 @@ resp_object *domain_system_load(const char *cmd, resp_object *args) {
}
resp_object *res = resp_array_init();
- char buf[64];
+ char buf[64];
resp_array_append_bulk(res, "1min");
snprintf(buf, sizeof(buf), "%.2f", loadavg[0]);
@@ -965,7 +959,7 @@ resp_object *domain_session_count(const char *cmd, resp_object *args) {
resp_object *res = malloc(sizeof(resp_object));
if (!res) return NULL;
res->type = RESPT_INT;
- res->u.i = (long long)count;
+ res->u.i = (long long)count;
return res;
}
@@ -979,7 +973,7 @@ int session_manager_pt(int64_t timestamp, struct pt_task *task) {
if (!udata->initialized) {
const char *ports_str = resp_map_get_string(udphole, "ports");
- int port_low = 7000, port_high = 7999;
+ int port_low = 7000, port_high = 7999;
if (ports_str) sscanf(ports_str, "%d-%d", &port_low, &port_high);
log_info("udphole: manager started with port range %d-%d", port_low, port_high);
udata->initialized = 1;
@@ -991,4 +985,4 @@ int session_manager_pt(int64_t timestamp, struct pt_task *task) {
}
return SCHED_RUNNING;
-}
-\ No newline at end of file
+}
diff --git a/src/domain/daemon/session.h b/src/domain/daemon/session.h
@@ -3,12 +3,12 @@
#include <stdint.h>
-#include "common/scheduler.h"
#include "common/resp.h"
+#include "common/scheduler.h"
typedef struct {
int64_t last_cleanup;
- int initialized;
+ int initialized;
} session_manager_udata_t;
int session_manager_pt(int64_t timestamp, struct pt_task *task);
diff --git a/src/infrastructure/config.c b/src/infrastructure/config.c
@@ -1,10 +1,12 @@
+#include "infrastructure/config.h"
+
#include <stdlib.h>
#include <string.h>
+
#include "benhoyt/inih.h"
-#include "rxi/log.h"
-#include "infrastructure/config.h"
#include "common/resp.h"
#include "domain/config.h"
+#include "rxi/log.h"
resp_object *pending_cfg = NULL;
@@ -19,7 +21,7 @@ static int config_handler(void *user, const char *section, const char *name, con
resp_map_set(cfg, section, sec);
sec = resp_map_get(cfg, section);
}
-
+
if (strcmp(name, "cluster") == 0) {
resp_object *arr = resp_map_get(sec, "cluster");
if (!arr) {
@@ -44,8 +46,8 @@ void config_init(void) {
pending_cfg = resp_array_init();
config_load(NULL, config_get_path());
resp_object *old = domain_cfg;
- domain_cfg = pending_cfg;
- pending_cfg = NULL;
+ domain_cfg = pending_cfg;
+ pending_cfg = NULL;
if (old) resp_free(old);
}
@@ -67,14 +69,14 @@ int config_reload(void) {
int r = config_load(NULL, config_get_path());
if (r < 0) return -1;
resp_object *old = domain_cfg;
- domain_cfg = pending_cfg;
- pending_cfg = NULL;
+ domain_cfg = pending_cfg;
+ pending_cfg = NULL;
if (old) resp_free(old);
return 0;
}
void config_set_path(const char *path) {
- if (stored_config_path) free((void*)stored_config_path);
+ if (stored_config_path) free((void *)stored_config_path);
stored_config_path = path ? strdup(path) : NULL;
}
diff --git a/src/infrastructure/config.h b/src/infrastructure/config.h
@@ -5,10 +5,10 @@
extern resp_object *pending_cfg;
-void config_init(void);
-int config_load(resp_object *cfg, const char *path);
-int config_reload(void);
-void config_set_path(const char *path);
+void config_init(void);
+int config_load(resp_object *cfg, const char *path);
+int config_reload(void);
+void config_set_path(const char *path);
const char *config_get_path(void);
-#endif
-\ No newline at end of file
+#endif
diff --git a/src/interface/api/server.c b/src/interface/api/server.c
@@ -6,67 +6,68 @@
* Runs as a protothread in the main select() loop.
*/
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
+#include "interface/api/server.h"
+
+#include <arpa/inet.h>
#include <ctype.h>
-#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <netdb.h>
+#include <unistd.h>
-#include "rxi/log.h"
-#include "tidwall/hashmap.h"
+#include "common/resp.h"
#include "common/scheduler.h"
#include "common/socket_util.h"
-#include "infrastructure/config.h"
#include "domain/config.h"
-#include "interface/api/server.h"
-#include "common/resp.h"
+#include "infrastructure/config.h"
+#include "rxi/log.h"
+#include "tidwall/hashmap.h"
int api_client_pt(int64_t timestamp, struct pt_task *task);
-#define API_MAX_CLIENTS 8
-#define READ_BUF_SIZE 4096
-#define WRITE_BUF_INIT 4096
-#define MAX_ARGS 32
+#define API_MAX_CLIENTS 8
+#define READ_BUF_SIZE 4096
+#define WRITE_BUF_INIT 4096
+#define MAX_ARGS 32
struct api_client_state {
- int fd;
- int *fds;
- int *ready_fds;
- int ready_fd;
- char *username;
- char rbuf[READ_BUF_SIZE];
- size_t rlen;
- char *wbuf;
- size_t wlen;
- size_t wcap;
+ int fd;
+ int *fds;
+ int *ready_fds;
+ int ready_fd;
+ char *username;
+ char rbuf[READ_BUF_SIZE];
+ size_t rlen;
+ char *wbuf;
+ size_t wlen;
+ size_t wcap;
};
typedef struct api_client_state api_client_t;
typedef struct {
- const char *name;
- char (*func)(api_client_t *c, char **args, int nargs);
+ const char *name;
+ char (*func)(api_client_t *c, char **args, int nargs);
} api_cmd_entry;
typedef struct {
- const char *name;
+ const char *name;
domain_cmd_fn func;
} domain_cmd_entry;
-static char *current_listen = NULL;
-static struct hashmap *cmd_map = NULL;
-static struct hashmap *domain_cmd_map = NULL;
+static char *current_listen = NULL;
+static struct hashmap *cmd_map = NULL;
+static struct hashmap *domain_cmd_map = NULL;
typedef struct {
- int *server_fds;
- int *ready_fds;
+ int *server_fds;
+ int *ready_fds;
} api_server_udata_t;
bool api_write_raw(api_client_t *c, const void *data, size_t len) {
@@ -118,7 +119,7 @@ bool api_write_array(api_client_t *c, size_t nitems) {
bool api_write_bulk_cstr(api_client_t *c, const char *s) {
if (!s) return api_write_nil(c);
size_t len = strlen(s);
- char prefix[32];
+ char prefix[32];
snprintf(prefix, sizeof(prefix), "$%zu\r\n", len);
if (!api_write_cstr(c, prefix)) return false;
if (!api_write_raw(c, s, len)) return false;
@@ -139,7 +140,7 @@ static void client_close(api_client_t *c) {
free(c->wbuf);
c->wbuf = NULL;
c->wlen = c->wcap = 0;
- c->rlen = 0;
+ c->rlen = 0;
free(c->username);
c->username = NULL;
}
@@ -148,8 +149,7 @@ static void client_flush(api_client_t *c) {
if (c->fd < 0 || c->wlen == 0) return;
ssize_t n = send(c->fd, c->wbuf, c->wlen, 0);
if (n > 0) {
- if ((size_t)n < c->wlen)
- memmove(c->wbuf, c->wbuf + n, c->wlen - (size_t)n);
+ if ((size_t)n < c->wlen) memmove(c->wbuf, c->wbuf + n, c->wlen - (size_t)n);
c->wlen -= (size_t)n;
} else if (n < 0 && errno != EAGAIN && errno != EWOULDBLOCK) {
client_close(c);
@@ -158,8 +158,7 @@ static void client_flush(api_client_t *c) {
static bool permit_matches(const char *pattern, const char *cmd) {
size_t plen = strlen(pattern);
- if (plen == 1 && pattern[0] == '*')
- return true;
+ if (plen == 1 && pattern[0] == '*') return true;
if (plen >= 2 && pattern[plen - 1] == '*') {
return strncasecmp(pattern, cmd, plen - 1) == 0;
}
@@ -167,7 +166,7 @@ static bool permit_matches(const char *pattern, const char *cmd) {
}
static bool user_has_permit(api_client_t *c, const char *cmd) {
- char section[128];
+ char section[128];
const char *uname = (c->username && c->username[0]) ? c->username : "*";
snprintf(section, sizeof(section), "user:%s", uname);
resp_object *sec = resp_map_get(domain_cfg, section);
@@ -180,8 +179,7 @@ static bool user_has_permit(api_client_t *c, const char *cmd) {
if (val->type == RESPT_ARRAY) {
for (size_t j = 0; j < val->u.arr.n; j++) {
resp_object *p = &val->u.arr.elem[j];
- if (p->type == RESPT_BULK && p->u.s && permit_matches(p->u.s, cmd))
- return true;
+ if (p->type == RESPT_BULK && p->u.s && permit_matches(p->u.s, cmd)) return true;
}
} else if (val->type == RESPT_BULK && val->u.s && permit_matches(val->u.s, cmd)) {
return true;
@@ -201,8 +199,7 @@ static bool user_has_permit(api_client_t *c, const char *cmd) {
if (val->type == RESPT_ARRAY) {
for (size_t j = 0; j < val->u.arr.n; j++) {
resp_object *p = &val->u.arr.elem[j];
- if (p->type == RESPT_BULK && p->u.s && permit_matches(p->u.s, cmd))
- return true;
+ if (p->type == RESPT_BULK && p->u.s && permit_matches(p->u.s, cmd)) return true;
}
} else if (val->type == RESPT_BULK && val->u.s && permit_matches(val->u.s, cmd)) {
return true;
@@ -228,9 +225,8 @@ static int cmd_compare(const void *a, const void *b, void *udata) {
}
void api_register_cmd(const char *name, char (*func)(api_client_t *, char **, int)) {
- if (!cmd_map)
- cmd_map = hashmap_new(sizeof(api_cmd_entry), 0, 0, 0, cmd_hash, cmd_compare, NULL, NULL);
- hashmap_set(cmd_map, &(api_cmd_entry){ .name = name, .func = func });
+ if (!cmd_map) cmd_map = hashmap_new(sizeof(api_cmd_entry), 0, 0, 0, cmd_hash, cmd_compare, NULL, NULL);
+ hashmap_set(cmd_map, &(api_cmd_entry){.name = name, .func = func});
log_trace("api: registered command '%s'", name);
}
@@ -249,21 +245,23 @@ static int domain_cmd_compare(const void *a, const void *b, void *udata) {
void api_register_domain_cmd(const char *name, domain_cmd_fn func) {
if (!domain_cmd_map)
domain_cmd_map = hashmap_new(sizeof(domain_cmd_entry), 0, 0, 0, domain_cmd_hash, domain_cmd_compare, NULL, NULL);
- hashmap_set(domain_cmd_map, &(domain_cmd_entry){ .name = name, .func = func });
+ hashmap_set(domain_cmd_map, &(domain_cmd_entry){.name = name, .func = func});
log_trace("api: registered domain command '%s'", name);
}
static char cmdAUTH(api_client_t *c, char **args, int nargs) {
if (nargs != 3) {
- api_write_err(c, "wrong number of arguments for 'auth' command (AUTH username password)");
+ api_write_err(c,
+ "wrong number of arguments for 'auth' command (AUTH "
+ "username password)");
return 1;
}
const char *uname = args[1];
const char *pass = args[2];
- char section[128];
+ char section[128];
snprintf(section, sizeof(section), "user:%s", uname);
- resp_object *sec = resp_map_get(domain_cfg, section);
- const char *secret = sec ? resp_map_get_string(sec, "secret") : NULL;
+ resp_object *sec = resp_map_get(domain_cfg, section);
+ const char *secret = sec ? resp_map_get_string(sec, "secret") : NULL;
if (secret && pass && strcmp(secret, pass) == 0) {
free(c->username);
c->username = strdup(uname);
@@ -277,15 +275,14 @@ static char cmdAUTH(api_client_t *c, char **args, int nargs) {
static char cmdPING(api_client_t *c, char **args, int nargs) {
(void)args;
- if (nargs == 1)
- return api_write_cstr(c, "+PONG\r\n") ? 1 : 0;
- if (nargs == 2)
- return api_write_bulk_cstr(c, args[1]) ? 1 : 0;
+ if (nargs == 1) return api_write_cstr(c, "+PONG\r\n") ? 1 : 0;
+ if (nargs == 2) return api_write_bulk_cstr(c, args[1]) ? 1 : 0;
return api_write_err(c, "wrong number of arguments for 'ping' command") ? 1 : 0;
}
static char cmdQUIT(api_client_t *c, char **args, int nargs) {
- (void)args; (void)nargs;
+ (void)args;
+ (void)nargs;
api_write_ok(c);
return 0;
}
@@ -294,23 +291,24 @@ static bool is_builtin(const char *name);
static char cmdCOMMAND(api_client_t *c, char **args, int nargs) {
(void)args;
- if (!cmd_map && !domain_cmd_map)
- return api_write_array(c, 0) ? 1 : 0;
+ if (!cmd_map && !domain_cmd_map) return api_write_array(c, 0) ? 1 : 0;
resp_object *result = resp_array_init();
if (!result) return 0;
if (domain_cmd_map) {
size_t iter = 0;
- void *item;
+ void *item;
while (hashmap_iter(domain_cmd_map, &iter, &item)) {
const domain_cmd_entry *e = item;
- if (!user_has_permit(c, e->name))
- continue;
+ if (!user_has_permit(c, e->name)) continue;
resp_array_append_bulk(result, e->name);
resp_object *meta = resp_array_init();
- if (!meta) { resp_free(result); return 0; }
+ if (!meta) {
+ resp_free(result);
+ return 0;
+ }
resp_array_append_bulk(meta, "summary");
resp_array_append_bulk(meta, "UDP hole proxy command");
resp_array_append_obj(result, meta);
@@ -319,22 +317,24 @@ static char cmdCOMMAND(api_client_t *c, char **args, int nargs) {
if (cmd_map) {
size_t iter = 0;
- void *item;
+ void *item;
while (hashmap_iter(cmd_map, &iter, &item)) {
const api_cmd_entry *e = item;
- if (!is_builtin(e->name) && !user_has_permit(c, e->name))
- continue;
+ if (!is_builtin(e->name) && !user_has_permit(c, e->name)) continue;
resp_array_append_bulk(result, e->name);
resp_object *meta = resp_array_init();
- if (!meta) { resp_free(result); return 0; }
+ if (!meta) {
+ resp_free(result);
+ return 0;
+ }
resp_array_append_bulk(meta, "summary");
resp_array_append_bulk(meta, "UDP hole proxy command");
resp_array_append_obj(result, meta);
}
}
- char *out_buf = NULL;
+ char *out_buf = NULL;
size_t out_len = 0;
if (resp_serialize(result, &out_buf, &out_len) != 0 || !out_buf) {
resp_free(result);
@@ -348,16 +348,14 @@ static char cmdCOMMAND(api_client_t *c, char **args, int nargs) {
}
static void init_builtins(void) {
- api_register_cmd("auth", cmdAUTH);
- api_register_cmd("ping", cmdPING);
- api_register_cmd("quit", cmdQUIT);
+ api_register_cmd("auth", cmdAUTH);
+ api_register_cmd("ping", cmdPING);
+ api_register_cmd("quit", cmdQUIT);
api_register_cmd("command", cmdCOMMAND);
}
static bool is_builtin(const char *name) {
- return (strcasecmp(name, "auth") == 0 ||
- strcasecmp(name, "ping") == 0 ||
- strcasecmp(name, "quit") == 0 ||
+ return (strcasecmp(name, "auth") == 0 || strcasecmp(name, "ping") == 0 || strcasecmp(name, "quit") == 0 ||
strcasecmp(name, "command") == 0);
}
@@ -366,7 +364,7 @@ static void dispatch_command(api_client_t *c, char **args, int nargs) {
for (char *p = args[0]; *p; p++) *p = (char)tolower((unsigned char)*p);
- const domain_cmd_entry *dcmd = hashmap_get(domain_cmd_map, &(domain_cmd_entry){ .name = args[0] });
+ const domain_cmd_entry *dcmd = hashmap_get(domain_cmd_map, &(domain_cmd_entry){.name = args[0]});
if (dcmd) {
if (!is_builtin(args[0])) {
if (!user_has_permit(c, args[0])) {
@@ -390,7 +388,7 @@ static void dispatch_command(api_client_t *c, char **args, int nargs) {
return;
}
- char *out_buf = NULL;
+ char *out_buf = NULL;
size_t out_len = 0;
if (resp_serialize(result, &out_buf, &out_len) != 0 || !out_buf) {
resp_free(result);
@@ -404,7 +402,7 @@ static void dispatch_command(api_client_t *c, char **args, int nargs) {
return;
}
- const api_cmd_entry *cmd = hashmap_get(cmd_map, &(api_cmd_entry){ .name = args[0] });
+ const api_cmd_entry *cmd = hashmap_get(cmd_map, &(api_cmd_entry){.name = args[0]});
if (!cmd) {
api_write_err(c, "unknown command");
return;
@@ -425,17 +423,17 @@ static void dispatch_command(api_client_t *c, char **args, int nargs) {
}
static int *create_listen_socket(const char *listen_addr) {
- const char *default_port = "6379";
- resp_object *api_sec = resp_map_get(domain_cfg, "udphole");
+ const char *default_port = "6379";
+ resp_object *api_sec = resp_map_get(domain_cfg, "udphole");
if (api_sec) {
const char *cfg_port = resp_map_get_string(api_sec, "port");
if (cfg_port && cfg_port[0]) default_port = cfg_port;
}
if (listen_addr && strncmp(listen_addr, "unix://", 7) == 0) {
- const char *socket_path = listen_addr + 7;
+ const char *socket_path = listen_addr + 7;
const char *socket_owner = api_sec ? resp_map_get_string(api_sec, "socket_owner") : NULL;
- int *fds = unix_listen(socket_path, SOCK_STREAM, socket_owner);
+ int *fds = unix_listen(socket_path, SOCK_STREAM, socket_owner);
if (!fds) {
return NULL;
}
@@ -453,8 +451,8 @@ static int *create_listen_socket(const char *listen_addr) {
static void handle_accept(int ready_fd) {
struct sockaddr_storage addr;
- socklen_t addrlen = sizeof(addr);
- int fd = accept(ready_fd, (struct sockaddr *)&addr, &addrlen);
+ socklen_t addrlen = sizeof(addr);
+ int fd = accept(ready_fd, (struct sockaddr *)&addr, &addrlen);
if (fd < 0) return;
set_socket_nonblocking(fd, 1);
@@ -484,8 +482,8 @@ int api_server_pt(int64_t timestamp, struct pt_task *task) {
}
if (udata->server_fds == NULL) {
- resp_object *api_sec = resp_map_get(domain_cfg, "udphole");
- const char *listen_str = api_sec ? resp_map_get_string(api_sec, "listen") : NULL;
+ resp_object *api_sec = resp_map_get(domain_cfg, "udphole");
+ const char *listen_str = api_sec ? resp_map_get_string(api_sec, "listen") : NULL;
if (!listen_str || !listen_str[0]) {
return SCHED_RUNNING;
@@ -538,7 +536,7 @@ int api_client_pt(int64_t timestamp, struct pt_task *task) {
return SCHED_RUNNING;
}
- char buf[1];
+ char buf[1];
ssize_t n = recv(state->fd, buf, 1, MSG_PEEK);
if (n <= 0) {
goto cleanup;
@@ -560,12 +558,12 @@ int api_client_pt(int64_t timestamp, struct pt_task *task) {
}
char *args[MAX_ARGS];
- int nargs = 0;
+ int nargs = 0;
for (size_t i = 0; i < cmd->u.arr.n && nargs < MAX_ARGS; i++) {
resp_object *elem = &cmd->u.arr.elem[i];
if (elem->type == RESPT_BULK && elem->u.s) {
args[nargs++] = elem->u.s;
- elem->u.s = NULL;
+ elem->u.s = NULL;
} else if (elem->type == RESPT_SIMPLE) {
args[nargs++] = elem->u.s ? elem->u.s : "";
}
@@ -597,4 +595,4 @@ cleanup:
free(state->username);
free(state);
return SCHED_DONE;
-}
-\ No newline at end of file
+}
diff --git a/src/interface/api/server.h b/src/interface/api/server.h
@@ -1,11 +1,11 @@
#ifndef UDPHOLE_API_SERVER_H
#define UDPHOLE_API_SERVER_H
-#include <stdint.h>
#include <stdbool.h>
+#include <stdint.h>
-#include "common/scheduler.h"
#include "common/resp.h"
+#include "common/scheduler.h"
struct api_client_state;
typedef struct api_client_state api_client_t;
diff --git a/src/interface/cli/command/cluster.c b/src/interface/cli/command/cluster.c
@@ -1,20 +1,20 @@
+#include "domain/cluster/cluster.h"
+
+#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
#include <sys/stat.h>
+#include <unistd.h>
+#include "../common.h"
#include "cofyc/argparse.h"
-#include "rxi/log.h"
-
-#include "infrastructure/config.h"
#include "common/resp.h"
-#include "../common.h"
#include "common/scheduler.h"
#include "domain/config.h"
-#include "domain/cluster/cluster.h"
+#include "infrastructure/config.h"
#include "interface/api/server.h"
+#include "rxi/log.h"
static void register_cluster_commands(void) {
api_register_domain_cmd("session.create", cluster_session_create);
@@ -38,8 +38,7 @@ static int do_daemonize(void) {
log_fatal("fork: %m");
return -1;
}
- if (pid > 0)
- _exit(0);
+ if (pid > 0) _exit(0);
if (setsid() < 0) {
log_fatal("setsid: %m");
_exit(1);
@@ -49,33 +48,31 @@ static int do_daemonize(void) {
log_fatal("fork: %m");
_exit(1);
}
- if (pid > 0)
- _exit(0);
- if (chdir("/") != 0) {}
+ if (pid > 0) _exit(0);
+ if (chdir("/") != 0) {
+ }
int fd;
- for (fd = 0; fd < 3; fd++)
- (void)close(fd);
+ for (fd = 0; fd < 3; fd++) (void)close(fd);
fd = open("/dev/null", O_RDWR);
if (fd >= 0) {
dup2(fd, STDIN_FILENO);
dup2(fd, STDOUT_FILENO);
dup2(fd, STDERR_FILENO);
- if (fd > 2)
- close(fd);
+ if (fd > 2) close(fd);
}
return 0;
}
int cli_cmd_cluster(int argc, const char **argv) {
- int daemonize_flag = 0;
+ int daemonize_flag = 0;
int no_daemonize_flag = 0;
- struct argparse argparse;
+ struct argparse argparse;
struct argparse_option options[] = {
- OPT_HELP(),
- OPT_BOOLEAN('d', "daemonize", &daemonize_flag, "run in background", NULL, 0, 0),
- OPT_BOOLEAN('D', "no-daemonize", &no_daemonize_flag, "force foreground", NULL, 0, 0),
- OPT_END(),
+ OPT_HELP(),
+ OPT_BOOLEAN('d', "daemonize", &daemonize_flag, "run in background", NULL, 0, 0),
+ OPT_BOOLEAN('D', "no-daemonize", &no_daemonize_flag, "force foreground", NULL, 0, 0),
+ OPT_END(),
};
argparse_init(&argparse, options, (const char *const[]){"udphole cluster", NULL}, ARGPARSE_STOP_AT_NON_OPTION);
argparse_parse(&argparse, argc, argv);
diff --git a/src/interface/cli/command/daemon.c b/src/interface/cli/command/daemon.c
@@ -1,21 +1,21 @@
+#include "daemon.h"
+
+#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
#include <sys/stat.h>
+#include <unistd.h>
+#include "../common.h"
#include "cofyc/argparse.h"
-#include "rxi/log.h"
-
-#include "infrastructure/config.h"
#include "common/resp.h"
-#include "../common.h"
#include "common/scheduler.h"
#include "domain/config.h"
-#include "daemon.h"
-#include "interface/api/server.h"
#include "domain/daemon/session.h"
+#include "infrastructure/config.h"
+#include "interface/api/server.h"
+#include "rxi/log.h"
static void register_domain_commands(void) {
api_register_domain_cmd("session.create", domain_session_create);
@@ -39,8 +39,7 @@ static int do_daemonize(void) {
log_fatal("fork: %m");
return -1;
}
- if (pid > 0)
- _exit(0);
+ if (pid > 0) _exit(0);
if (setsid() < 0) {
log_fatal("setsid: %m");
_exit(1);
@@ -50,33 +49,31 @@ static int do_daemonize(void) {
log_fatal("fork: %m");
_exit(1);
}
- if (pid > 0)
- _exit(0);
- if (chdir("/") != 0) {}
+ if (pid > 0) _exit(0);
+ if (chdir("/") != 0) {
+ }
int fd;
- for (fd = 0; fd < 3; fd++)
- (void)close(fd);
+ for (fd = 0; fd < 3; fd++) (void)close(fd);
fd = open("/dev/null", O_RDWR);
if (fd >= 0) {
dup2(fd, STDIN_FILENO);
dup2(fd, STDOUT_FILENO);
dup2(fd, STDERR_FILENO);
- if (fd > 2)
- close(fd);
+ if (fd > 2) close(fd);
}
return 0;
}
int cli_cmd_daemon(int argc, const char **argv) {
- int daemonize_flag = 0;
+ int daemonize_flag = 0;
int no_daemonize_flag = 0;
- struct argparse argparse;
+ struct argparse argparse;
struct argparse_option options[] = {
- OPT_HELP(),
- OPT_BOOLEAN('d', "daemonize", &daemonize_flag, "run in background", NULL, 0, 0),
- OPT_BOOLEAN('D', "no-daemonize", &no_daemonize_flag, "force foreground", NULL, 0, 0),
- OPT_END(),
+ OPT_HELP(),
+ OPT_BOOLEAN('d', "daemonize", &daemonize_flag, "run in background", NULL, 0, 0),
+ OPT_BOOLEAN('D', "no-daemonize", &no_daemonize_flag, "force foreground", NULL, 0, 0),
+ OPT_END(),
};
argparse_init(&argparse, options, (const char *const[]){"udphole daemon", NULL}, ARGPARSE_STOP_AT_NON_OPTION);
argparse_parse(&argparse, argc, argv);
@@ -99,4 +96,4 @@ int cli_cmd_daemon(int argc, const char **argv) {
log_info("udphole: daemon started");
return sched_main();
-}
-\ No newline at end of file
+}
diff --git a/src/interface/cli/command/daemon.h b/src/interface/cli/command/daemon.h
@@ -3,4 +3,4 @@
int cli_cmd_daemon(int argc, const char **argv);
-#endif // UDPHOLE_CLI_DAEMON_H
-\ No newline at end of file
+#endif // UDPHOLE_CLI_DAEMON_H
diff --git a/src/interface/cli/command/list_commands.c b/src/interface/cli/command/list_commands.c
@@ -1,22 +1,25 @@
+#include "list_commands.h"
+
#include <stdio.h>
#include <string.h>
#include "../common.h"
-#include "list_commands.h"
int cli_cmd_list_commands(int argc, const char **argv) {
(void)argc;
(void)argv;
- int len;
- int name_longest = 0;
- struct cli_command *cmd = cli_commands;
- while(cmd) {
+ int len;
+ int name_longest = 0;
+ struct cli_command *cmd = cli_commands;
+ while (cmd) {
len = (int)strlen(cmd->cmd);
- if (len > name_longest) { name_longest = len; }
+ if (len > name_longest) {
+ name_longest = len;
+ }
cmd = cmd->next;
}
- int width = cli_get_output_width(80);
+ int width = cli_get_output_width(80);
int left_col = name_longest + 3;
printf("\n");
@@ -30,4 +33,4 @@ int cli_cmd_list_commands(int argc, const char **argv) {
printf("\n\n");
return 0;
-}
-\ No newline at end of file
+}
diff --git a/src/interface/cli/command/list_commands.h b/src/interface/cli/command/list_commands.h
@@ -3,4 +3,4 @@
int cli_cmd_list_commands(int argc, const char **argv);
-#endif // UDPHOLE_CLI_LIST_COMMANDS_H
-\ No newline at end of file
+#endif // UDPHOLE_CLI_LIST_COMMANDS_H
diff --git a/src/interface/cli/common.c b/src/interface/cli/common.c
@@ -1,26 +1,24 @@
+#include "common.h"
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <unistd.h>
#include <sys/ioctl.h>
-
-#include "common.h"
+#include <unistd.h>
#ifndef NULL
-#define NULL (void*)0
+#define NULL (void *)0
#endif
struct cli_command *cli_commands = NULL;
const char *cli_find_arg(int argc, const char **argv, const char *name) {
for (int i = 0; i < argc - 1; i++)
- if (strcmp(argv[i], name) == 0)
- return argv[i + 1];
+ if (strcmp(argv[i], name) == 0) return argv[i + 1];
return NULL;
}
-size_t cli_collect_positional(int argc, const char **argv, int start,
- const char **out, size_t max_out) {
+size_t cli_collect_positional(int argc, const char **argv, int start, const char **out, size_t max_out) {
size_t n = 0;
for (int i = start; i < argc && n < max_out; i++) {
if (argv[i][0] == '-' && argv[i][1] == '-' && argv[i][2] != '\0') {
@@ -47,21 +45,17 @@ const char *cli_resolve_default_config(void) {
}
int cli_get_output_width(int default_width) {
- if (!isatty(STDOUT_FILENO))
- return default_width;
+ if (!isatty(STDOUT_FILENO)) return default_width;
struct winsize w;
- if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &w) < 0 || w.ws_col <= 0)
- return default_width;
+ if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &w) < 0 || w.ws_col <= 0) return default_width;
return (int)w.ws_col;
}
void cli_print_wrapped(FILE *out, const char *text, int width, int left_col_width) {
- if (!text || width <= left_col_width)
- return;
+ if (!text || width <= left_col_width) return;
char *copy = strdup(text);
- if (!copy)
- return;
- int len = left_col_width;
+ if (!copy) return;
+ int len = left_col_width;
char *tok = strtok(copy, " ");
while (tok) {
int toklen = (int)strlen(tok);
@@ -69,8 +63,7 @@ void cli_print_wrapped(FILE *out, const char *text, int width, int left_col_widt
fprintf(out, "\n%*s", left_col_width, "");
len = left_col_width;
}
- if (len > left_col_width)
- fputc(' ', out);
+ if (len > left_col_width) fputc(' ', out);
fputs(tok, out);
len += (len > left_col_width ? 1 : 0) + toklen;
tok = strtok(NULL, " ");
@@ -80,21 +73,21 @@ void cli_print_wrapped(FILE *out, const char *text, int width, int left_col_widt
void cli_register_command(const char *name, const char *description, int (*fn)(int, const char **)) {
struct cli_command *cmd = malloc(sizeof(*cmd));
- cmd->cmd = name;
- cmd->desc = description;
- cmd->fn = fn;
- cmd->next = cli_commands;
- cli_commands = cmd;
+ cmd->cmd = name;
+ cmd->desc = description;
+ cmd->fn = fn;
+ cmd->next = cli_commands;
+ cli_commands = cmd;
}
int cli_execute_command(int argc, const char **argv) {
struct cli_command *cmd = cli_commands;
- while(cmd) {
+ while (cmd) {
if (!strcmp(cmd->cmd, argv[0])) return cmd->fn(argc, argv);
cmd = cmd->next;
}
fprintf(stderr, "Unknown command: %s\n", argv[0]);
return 1;
-}
-\ No newline at end of file
+}
diff --git a/src/interface/cli/common.h b/src/interface/cli/common.h
@@ -5,7 +5,7 @@
#include <stdio.h>
struct cli_command {
- void *next;
+ void *next;
const char *cmd;
const char *desc;
int (*fn)(int, const char **);
@@ -15,10 +15,9 @@ extern struct cli_command *cli_commands;
const char *cli_find_arg(int argc, const char **argv, const char *name);
-size_t cli_collect_positional(int argc, const char **argv, int start,
- const char **out, size_t max_out);
+size_t cli_collect_positional(int argc, const char **argv, int start, const char **out, size_t max_out);
-void cli_set_config_path(const char *path);
+void cli_set_config_path(const char *path);
const char *cli_config_path(void);
const char *cli_resolve_default_config(void);
@@ -28,6 +27,6 @@ int cli_get_output_width(int default_width);
void cli_print_wrapped(FILE *out, const char *text, int width, int left_col_width);
void cli_register_command(const char *name, const char *description, int (*fn)(int, const char **));
-int cli_execute_command(int argc, const char **argv);
+int cli_execute_command(int argc, const char **argv);
-#endif // UDPHOLE_CLI_COMMON_H
-\ No newline at end of file
+#endif // UDPHOLE_CLI_COMMON_H
diff --git a/src/interface/cli/main.c b/src/interface/cli/main.c
@@ -2,21 +2,20 @@
extern "C" {
#endif
+#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
-#include <signal.h>
#include "cofyc/argparse.h"
-#include "rxi/log.h"
-
-#include "interface/cli/common.h"
-#include "interface/cli/command/list_commands.h"
-#include "interface/cli/command/daemon.h"
-#include "interface/cli/command/cluster.h"
-#include "infrastructure/config.h"
#include "domain/cluster/cluster.h"
+#include "infrastructure/config.h"
+#include "interface/cli/command/cluster.h"
+#include "interface/cli/command/daemon.h"
+#include "interface/cli/command/list_commands.h"
+#include "interface/cli/common.h"
+#include "rxi/log.h"
#ifdef __cplusplus
}
@@ -27,14 +26,14 @@ extern "C" {
INCTXT(License, "LICENSE.md");
static const char *const usages[] = {
- "udphole [global] command [local]",
- "udphole list-commands",
- "udphole --license",
- NULL,
+ "udphole [global] command [local]",
+ "udphole list-commands",
+ "udphole --license",
+ NULL,
};
-static FILE *log_file;
-static char *log_path;
+static FILE *log_file;
+static char *log_path;
static volatile sig_atomic_t sighup_received;
static void logfile_callback(log_Event *ev) {
@@ -62,7 +61,7 @@ static void sighup_handler(int sig) {
sighup_received = 1;
}
-#define MARKER_PARAGRAPH "<!-- paragraph -->"
+#define MARKER_PARAGRAPH "<!-- paragraph -->"
#define MARKER_LIST_START "<!-- list:start -->"
#define MARKER_LIST_END "<!-- list:end -->"
@@ -76,7 +75,7 @@ static void print_license_paragraph(const char *start, const char *end, int widt
while (end > start && (end[-1] == ' ' || end[-1] == '\n' || end[-1] == '\r')) end--;
if (start >= end) return;
static char buf[4096];
- size_t n = (size_t)(end - start);
+ size_t n = (size_t)(end - start);
if (n >= sizeof(buf)) n = sizeof(buf) - 1;
memcpy(buf, start, n);
buf[n] = '\0';
@@ -88,24 +87,30 @@ static void print_license_paragraph(const char *start, const char *end, int widt
}
static void print_license_list(const char *start, const char *end, int width) {
- const int left_col = 5;
- const char *p = start;
+ const int left_col = 5;
+ const char *p = start;
while (p < end) {
skip_whitespace(&p);
if (p >= end) break;
- if (*p < '0' || *p > '9') { p++; continue; }
+ if (*p < '0' || *p > '9') {
+ p++;
+ continue;
+ }
const char *num_start = p;
while (p < end && *p >= '0' && *p <= '9') p++;
if (p >= end || *p != '.') continue;
p++;
skip_whitespace(&p);
const char *text_start = p;
- const char *item_end = p;
+ const char *item_end = p;
while (item_end < end) {
const char *next = item_end;
while (next < end && *next != '\n') next++;
if (next < end) next++;
- if (next >= end) { item_end = end; break; }
+ if (next >= end) {
+ item_end = end;
+ break;
+ }
skip_whitespace(&next);
if (next < end && *next >= '0' && *next <= '9') {
const char *q = next;
@@ -118,7 +123,7 @@ static void print_license_list(const char *start, const char *end, int width) {
int num = atoi(num_start);
fprintf(stdout, " %2d. ", num);
static char buf[1024];
- size_t n = (size_t)(item_end - text_start);
+ size_t n = (size_t)(item_end - text_start);
if (n >= sizeof(buf)) n = sizeof(buf) - 1;
memcpy(buf, text_start, n);
buf[n] = '\0';
@@ -140,8 +145,7 @@ static void cli_print_license(FILE *out, const char *text, int width) {
print_license_paragraph(p, p + strlen(p), width);
break;
}
- if (q > p)
- print_license_paragraph(p, q, width);
+ if (q > p) print_license_paragraph(p, q, width);
q += 5;
if (strncmp(q, "paragraph -->", 13) == 0) {
q += 13;
@@ -156,8 +160,7 @@ static void cli_print_license(FILE *out, const char *text, int width) {
q += 14;
skip_whitespace(&q);
const char *r = strstr(q, "<!-- list:end -->");
- if (r)
- print_license_list(q, r, width);
+ if (r) print_license_list(q, r, width);
p = r ? r + 17 : q + strlen(q);
continue;
}
@@ -166,37 +169,26 @@ static void cli_print_license(FILE *out, const char *text, int width) {
}
int main(int argc, const char **argv) {
- const char *loglevel = "info";
+ const char *loglevel = "info";
const char *logfile_path = NULL;
- const char *config_path = NULL;
- static int license_flag = 0;
+ const char *config_path = NULL;
+ static int license_flag = 0;
- cli_register_command(
- "list-commands",
- "Displays known commands and their descriptions",
- cli_cmd_list_commands
- );
+ cli_register_command("list-commands", "Displays known commands and their descriptions", cli_cmd_list_commands);
- cli_register_command(
- "daemon",
- "Run the udphole daemon",
- cli_cmd_daemon
- );
+ cli_register_command("daemon", "Run the udphole daemon", cli_cmd_daemon);
- cli_register_command(
- "cluster",
- "Run the udphole cluster",
- cli_cmd_cluster
- );
+ cli_register_command("cluster", "Run the udphole cluster", cli_cmd_cluster);
- struct argparse argparse;
+ struct argparse argparse;
struct argparse_option options[] = {
- OPT_HELP(),
- OPT_STRING('f', "config", &config_path, "config file path (default: auto-detect)", NULL, 0, 0),
- OPT_STRING('v', "verbosity", &loglevel, "log verbosity: fatal,error,warn,info,debug,trace (default: info)", NULL, 0, 0),
- OPT_STRING(0, "log", &logfile_path, "also write log to file (SIGHUP reopens for logrotate)", NULL, 0, 0),
- OPT_BOOLEAN(0, "license", &license_flag, "print license and exit", NULL, 0, 0),
- OPT_END(),
+ OPT_HELP(),
+ OPT_STRING('f', "config", &config_path, "config file path (default: auto-detect)", NULL, 0, 0),
+ OPT_STRING('v', "verbosity", &loglevel, "log verbosity: fatal,error,warn,info,debug,trace (default: info)", NULL,
+ 0, 0),
+ OPT_STRING(0, "log", &logfile_path, "also write log to file (SIGHUP reopens for logrotate)", NULL, 0, 0),
+ OPT_BOOLEAN(0, "license", &license_flag, "print license and exit", NULL, 0, 0),
+ OPT_END(),
};
argparse_init(&argparse, options, usages, ARGPARSE_STOP_AT_NON_OPTION);
argc = argparse_parse(&argparse, argc, argv);
@@ -211,8 +203,7 @@ int main(int argc, const char **argv) {
return 1;
}
- if (!config_path || !config_path[0])
- config_path = cli_resolve_default_config();
+ if (!config_path || !config_path[0]) config_path = cli_resolve_default_config();
config_set_path(config_path);
config_init();
@@ -238,8 +229,8 @@ int main(int argc, const char **argv) {
log_set_level(level);
setvbuf(stderr, NULL, _IOLBF, 0);
- log_file = NULL;
- log_path = NULL;
+ log_file = NULL;
+ log_path = NULL;
sighup_received = 0;
if (logfile_path && logfile_path[0]) {
@@ -256,4 +247,4 @@ int main(int argc, const char **argv) {
}
return cli_execute_command(argc, argv);
-}
-\ No newline at end of file
+}