summaryrefslogtreecommitdiff
path: root/server.c
diff options
context:
space:
mode:
authorGravatar moon <moon@coffin.ir> 2025-09-13 00:51:54 +0330
committerGravatar moon <moon@coffin.ir> 2025-09-13 00:51:54 +0330
commit59a134f2d68a6b27e8bd4e2c31794bd8f2dad6e8 (patch)
tree07a85376425a0393ce2557e87adb6a7dd0aa4a02 /server.c
parentbug fixes (diff)
new things
Diffstat (limited to 'server.c')
-rw-r--r--server.c79
1 files changed, 65 insertions, 14 deletions
diff --git a/server.c b/server.c
index 9715467..a88b6f8 100644
--- a/server.c
+++ b/server.c
@@ -45,7 +45,7 @@ struct {
.minor_version = 1,
.motd = "A moonpaste server.", // minecraft much?
.retention_hours = 168, // 1 week
- .leading_zeros = 10, // the moon guarantee
+ .leading_zeros = 12, // the moon guarantee
.accepts_plain = true, // probably legal
};
@@ -145,9 +145,9 @@ void* propagate_packet(void* _packet) {
void save_packet(const struct data_packet packet);
-#define reply(__len, __stream) \
+#define reply(__len, ...) \
({ \
- *out = (byte*) __stream; \
+ *out = (byte*) __VA_ARGS__; \
*out_len = __len; \
})
@@ -363,6 +363,14 @@ void paste_server(
return;
}
+ if (current_time - packet.contents.created_time_ms
+ > server_stats.retention_hours * (60 * 60 * 1000)) {
+ log(_warn, "expired\n");
+ output_data[ 1 ] = false;
+ reply(output_len, output_data);
+ return;
+ }
+
if (!packet.contents.encrypted && !server_stats.accepts_plain) {
log(_warn, "plaintext not accepted by server\n");
output_data[ 1 ] = false;
@@ -433,6 +441,14 @@ void paste_server(
bool success;
req = s2firehose_request(in_len - 1, in + 1, &success);
+ if (!success) {
+ byte* output_data = calloc(1 + 14, sizeof(byte));
+ output_data[ 0 ] = error;
+ memcpy(output_data + 1, "invalid request", 14);
+ reply(15, output_data);
+ return;
+ }
+
if (unlikely(req.count > 64)) req.count = 64; // clamp
log(_info,
@@ -442,14 +458,6 @@ void paste_server(
req.count,
req.offset);
- if (!success) {
- byte* output_data = calloc(1 + 14, sizeof(byte));
- output_data[ 0 ] = error;
- memcpy(output_data + 1, "invalid request", 14);
- reply(15, output_data);
- return;
- }
-
water_splash entries[ req.count ];
uint16_t copied_count = firehose_get_packets(req.offset, req.count, entries);
@@ -481,9 +489,48 @@ void paste_server(
}
case register_neighbor: {
- // TODO
- }
- // break;
+ bool success;
+ struct relay_neighbor neighbor = s2relay_neighbor(in_len - 1, in + 1, &success);
+
+ if (!success) {
+ byte* output_data = calloc(1 + 14, sizeof(byte));
+ output_data[ 0 ] = error;
+ memcpy(output_data + 1, "invalid request", 14);
+ reply(15, output_data);
+ return;
+ }
+
+ log(_info, "<%.*s> request type: neighbor registration\n", (int) ip_size, ip_addr);
+
+ char ip_string[ INET6_ADDRSTRLEN ];
+
+ if (neighbor.has_ipv4) {
+ sprintf(
+ ip_string,
+ "%d.%d.%d.%d",
+ neighbor.v4_addr[ 0 ],
+ neighbor.v4_addr[ 1 ],
+ neighbor.v4_addr[ 2 ],
+ neighbor.v4_addr[ 3 ]);
+ } else if (neighbor.has_ipv6) {
+ int offset = 0;
+ for (int j = 0; j < 8; j++) {
+ uint16_t word
+ = (neighbor.v6_addr[ j * 2 ] << 8) | neighbor.v6_addr[ j * 2 + 1 ];
+ offset += sprintf(ip_string + offset, "%x%s", word, (j < 7) ? ":" : "");
+ }
+ }
+
+ struct relay_info audit_result = run_server_audit(ip_string, default_port);
+ if (!audit_result.capabilities.can_store && audit_result.major_version == 0
+ && audit_result.minor_version == 0) {
+ // invalid
+ reply(2, (byte[ 2 ]) { error, 0 });
+ break;
+ }
+
+ reply(2, (byte[ 2 ]) { register_neighbor_result, add_neighbor(neighbor) });
+ } break;
default: {
log(_info, "<%.*s> request type: invalid method\n", (int) ip_size, ip_addr);
@@ -643,6 +690,10 @@ void* cleanup_packets(void* arg) {
pthread_mutex_unlock(&packet_storage_mutex);
}
+ // external cleanup
+ system("find packets/ -mtime +7 -delete");
+
+ // disk cleanup, tho not sure this is needed
DIR* dir = opendir("packets");
if (dir) {
struct dirent* entry;