diff --git a/fastsync_client b/fastsync_client index c5a0f4f..3056e44 100755 Binary files a/fastsync_client and b/fastsync_client differ diff --git a/src/client.c b/src/client.c index 7a0f4cd..c07f3e6 100644 --- a/src/client.c +++ b/src/client.c @@ -71,153 +71,6 @@ typedef struct { static atomic_uint_fast64_t g_bytes_sent = 0; static atomic_uint_fast32_t g_files_sent = 0; -// ─── UDP helpers ────────────────────────────────────────────────────────── - -static int verify_and_resend(sync_ctx_t *ctx, int file_fd, - uint32_t file_id, uint64_t file_size) { - uint32_t total_blocks = (file_size + UDP_PAYLOAD_MAX - 1) / UDP_PAYLOAD_MAX; - - while (1) { - uint32_t req = MAGIC_VERIFY; - if (writen(ctx->tcp_fd, &req, sizeof(req)) != sizeof(req)) return -1; - if (writen(ctx->tcp_fd, &file_id, sizeof(file_id)) != sizeof(file_id)) return -1; - - uint32_t missing = 0; - if (readn(ctx->tcp_fd, &missing, sizeof(missing)) != sizeof(missing)) return -1; - if (missing == 0) break; - - uint32_t *ids = malloc(missing * sizeof(uint32_t)); - if (!ids) { perror("malloc"); return -1; } - if (readn(ctx->tcp_fd, ids, missing * sizeof(uint32_t)) - != (ssize_t)(missing * sizeof(uint32_t))) { free(ids); return -1; } - - printf("[thread] Resending %u missing blocks...\n", missing); - for (uint32_t i = 0; i < missing; i++) { - uint32_t bid = ids[i]; - if (bid >= total_blocks) continue; - uint64_t off = (uint64_t)bid * UDP_PAYLOAD_MAX; - if (lseek(file_fd, off, SEEK_SET) == (off_t)-1) { perror("lseek"); continue; } - - char payload[UDP_PAYLOAD_MAX]; - ssize_t nr = read(file_fd, payload, UDP_PAYLOAD_MAX); - if (nr <= 0) continue; - - udp_packet_header_t hdr; - hdr.magic = MAGIC_UDP_DATA; - hdr.session_id = ctx->udp_session_id; - hdr.file_id = file_id; - hdr.block_id = bid; - hdr.block_offset = off; - hdr.payload_len = nr; - - char pkt[sizeof(hdr) + UDP_PAYLOAD_MAX]; - memcpy(pkt, &hdr, sizeof(hdr)); - memcpy(pkt + sizeof(hdr), payload, nr); - sendto(ctx->udp_fd, pkt, sizeof(hdr) + nr, 0, - (struct sockaddr *)&ctx->udp_server_addr, - sizeof(ctx->udp_server_addr)); - } - free(ids); - } - return 0; -} - -static int send_file_udp(sync_ctx_t *ctx, const char *full_path, - uint32_t file_id, uint64_t file_size) { - int fd = open(full_path, O_RDONLY); - if (fd < 0) { perror("open"); return -1; } - - uint32_t total = (file_size + UDP_PAYLOAD_MAX - 1) / UDP_PAYLOAD_MAX; - printf("[thread] UDP send: %s (%u blocks)\n", full_path, total); - - for (uint32_t bid = 0; bid < total; bid++) { - char payload[UDP_PAYLOAD_MAX]; - ssize_t nr = read(fd, payload, UDP_PAYLOAD_MAX); - if (nr <= 0) break; - - udp_packet_header_t hdr; - hdr.magic = MAGIC_UDP_DATA; - hdr.session_id = ctx->udp_session_id; - hdr.file_id = file_id; - hdr.block_id = bid; - hdr.block_offset = (uint64_t)bid * UDP_PAYLOAD_MAX; - hdr.payload_len = nr; - - char pkt[sizeof(hdr) + UDP_PAYLOAD_MAX]; - memcpy(pkt, &hdr, sizeof(hdr)); - memcpy(pkt + sizeof(hdr), payload, nr); - sendto(ctx->udp_fd, pkt, sizeof(hdr) + nr, 0, - (struct sockaddr *)&ctx->udp_server_addr, - sizeof(ctx->udp_server_addr)); - } - - int ret = verify_and_resend(ctx, fd, file_id, file_size); - close(fd); - return ret; -} - -// ─── Send a single file over one connection (TCP or UDP data) ───────────── - -static int send_one_file(sync_ctx_t *ctx, const char *full_path, - const char *rel_path) { - struct stat st; - if (stat(full_path, &st) < 0) { perror("stat"); return -1; } - - file_meta_t meta; - meta.magic = MAGIC_META; - meta.name_len = strlen(rel_path); - meta.file_size = st.st_size; - meta.mode = st.st_mode; - - if (writen(ctx->tcp_fd, &meta, sizeof(meta)) != sizeof(meta)) return -1; - if (writen(ctx->tcp_fd, rel_path, meta.name_len) != (ssize_t)meta.name_len) return -1; - - file_response_t resp; - if (readn(ctx->tcp_fd, &resp, sizeof(resp)) != sizeof(resp)) return -1; - - if (resp.response == RESP_SKIP) { - printf("[thread] Skip: %s\n", rel_path); - return 0; - } else if (resp.response == RESP_USE_UDP) { - if (send_file_udp(ctx, full_path, resp.file_id, meta.file_size) < 0) - return -1; - uint32_t ack = 0; - if (readn(ctx->tcp_fd, &ack, sizeof(ack)) != sizeof(ack) - || ack != RESP_OK) { - fprintf(stderr, "[thread] UDP finalize failed: %s\n", rel_path); - return -1; - } - } else if (resp.response == RESP_SEND_DATA) { - int fd = open(full_path, O_RDONLY); - if (fd < 0) { perror("open"); return -1; } - off_t off = 0; - while (off < (off_t)meta.file_size) { - ssize_t r = sendfile(ctx->tcp_fd, fd, &off, meta.file_size - off); - if (r < 0) { - if (errno == EINTR) continue; - perror("sendfile"); close(fd); return -1; - } - if (r == 0) break; - } - close(fd); - uint32_t ack = 0; - if (readn(ctx->tcp_fd, &ack, sizeof(ack)) != sizeof(ack) - || ack != RESP_OK) { - fprintf(stderr, "[thread] TCP finalize failed: %s\n", rel_path); - return -1; - } - } else { - fprintf(stderr, "[thread] Server rejected %s (code %u)\n", - rel_path, resp.response); - return -1; - } - - atomic_fetch_add(&g_bytes_sent, meta.file_size); - atomic_fetch_add(&g_files_sent, 1); - printf("[thread] Sent: %s\n", rel_path); - return 0; -} - // ─── UDP session setup (called once per worker if -u) ───────────────────── static int setup_udp(sync_ctx_t *ctx, const char *host) { @@ -473,7 +326,7 @@ static int collect_files(const char *base, const char *sub, file_task_t **list, while ((e = readdir(dir)) != NULL) { if (!strcmp(e->d_name, ".") || !strcmp(e->d_name, "..")) continue; - char rel[2048], full[2048]; + char rel[1024], full[2048]; if (sub && sub[0]) { snprintf(rel, sizeof(rel), "%s/%s", sub, e->d_name); } else { diff --git a/src/client.o b/src/client.o index 610e11a..aa3bef0 100644 Binary files a/src/client.o and b/src/client.o differ diff --git a/src/server.c b/src/server.c index 2b6ba7c..7fb59db 100644 --- a/src/server.c +++ b/src/server.c @@ -353,7 +353,7 @@ void handle_client(int sock_fd, const char *dest_dir) { // Check if file already exists with same size and checksum (skip if so) struct stat existing_st; if (stat(target_path, &existing_st) == 0 && - existing_st.st_size == meta.file_size && + (uint64_t)existing_st.st_size == meta.file_size && S_ISREG(existing_st.st_mode)) { // File exists with same size - check checksum uint64_t existing_checksum = fast_hash_file(target_path, meta.file_size);