int main(int argc, char *argv[]) { int listenFd, acceptFd, connFd; socklen_t len; /* Size of socket address buffer */ void *addr; /* Buffer for socket address */ char addrStr[IS_ADDR_STR_LEN]; if (argc != 2 || strcmp(argv[1], "--help") == 0) usageErr("%s service\n", argv[0]); /* Create listening socket, obtain size of address structure */ listenFd = inetListen(argv[1], 5, &len); if (listenFd == -1) errExit("inetListen"); connFd = inetConnect(NULL, argv[1], SOCK_STREAM); if (connFd == -1) errExit("inetConnect"); acceptFd = accept(listenFd, NULL, NULL); if (acceptFd == -1) errExit("accept"); addr = malloc(len); if (addr == NULL) errExit("malloc"); if (getsockname(connFd, addr, &len) == -1) errExit("getsockname"); printf("getsockname(connFd): %s\n", inetAddressStr(addr, len, addrStr, IS_ADDR_STR_LEN)); if (getsockname(acceptFd, addr, &len) == -1) errExit("getsockname"); printf("getsockname(acceptFd): %s\n", inetAddressStr(addr, len, addrStr, IS_ADDR_STR_LEN)); if (getpeername(connFd, addr, &len) == -1) errExit("getpeername"); printf("getpeername(connFd): %s\n", inetAddressStr(addr, len, addrStr, IS_ADDR_STR_LEN)); if (getpeername(acceptFd, addr, &len) == -1) errExit("getpeername"); printf("getpeername(acceptFd): %s\n", inetAddressStr(addr, len, addrStr, IS_ADDR_STR_LEN)); sleep(30); /* Give us time to run netstat(8) */ exit(EXIT_SUCCESS); }
int main(int argc, char *argv[]) { int sfd; ssize_t numRead; socklen_t len; struct sockaddr_storage claddr; char buf[BUF_SIZE]; char addrStr[IS_ADDR_STR_LEN]; if (becomeDaemon(0) == -1) errExit("becomeDaemon"); sfd = inetBind(SERVICE, SOCK_DGRAM, NULL); if (sfd == -1) { syslog(LOG_ERR, "Could not create server socket (%s)", strerror(errno)); exit(EXIT_FAILURE); } /* Receive datagrams and return copies to senders */ for (;;) { len = sizeof(struct sockaddr_storage); numRead = recvfrom(sfd, buf, BUF_SIZE, 0, (struct sockaddr *) &claddr, &len); if (numRead == -1) errExit("recvfrom"); if (sendto(sfd, buf, numRead, 0, (struct sockaddr *) &claddr, len) != numRead) syslog(LOG_WARNING, "Error echoing response to %s (%s)", inetAddressStr((struct sockaddr *) &claddr, len, addrStr, IS_ADDR_STR_LEN), strerror(errno)); } }
int main(int argc, char *argv[]) { uint32_t seqNum; char reqLenStr[INT_LEN]; /* Length of requested sequence */ char seqNumStr[INT_LEN]; /* Start of granted sequence */ struct sockaddr *claddr; int lfd, cfd, reqLen; socklen_t addrlen, alen; char addrStr[IS_ADDR_STR_LEN]; if (argc > 1 && strcmp(argv[1], "--help") == 0) usageErr("%s [init-seq-num]\n", argv[0]); seqNum = (argc > 1) ? getInt(argv[1], 0, "init-seq-num") : 0; /* Ignore the SIGPIPE signal, so that we find out about broken connection errors via a failure from write(). */ if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) errExit("signal"); lfd = inetListen(PORT_NUM_STR, 5, &addrlen); if (lfd == -1) fatal("inetListen() failed"); /* Allocate a buffer large enough to hold the client's socket address */ claddr = malloc(addrlen); if (claddr == NULL) errExit("malloc"); for (;;) { /* Handle clients iteratively */ /* Accept a client connection, obtaining client's address */ alen = addrlen; cfd = accept(lfd, (struct sockaddr *) claddr, &alen); if (cfd == -1) { errMsg("accept"); continue; } printf("Connection from %s\n", inetAddressStr(claddr, alen, addrStr, IS_ADDR_STR_LEN)); /* Read client request, send sequence number back */ if (readLine(cfd, reqLenStr, INT_LEN) <= 0) { close(cfd); continue; /* Failed read; skip request */ } reqLen = atoi(reqLenStr); if (reqLen <= 0) { /* Watch for misbehaving clients */ close(cfd); continue; /* Bad request; skip it */ } snprintf(seqNumStr, INT_LEN, "%d\n", seqNum); if (write(cfd, &seqNumStr, strlen(seqNumStr)) != strlen(seqNumStr)) fprintf(stderr, "Error on write"); seqNum += reqLen; /* Update sequence number */ if (close(cfd) == -1) /* Close connection */ errMsg("close"); } }
int handleClient(int cfd, struct sockaddr *claddr, socklen_t *addrlen) { long long tbytes = 0; // total number of transfered bytes char addrstr[IS_ADDR_STR_LEN]; errMsg(LOG_INFO, "Connection from %s", inetAddressStr(claddr, *addrlen, addrstr, IS_ADDR_STR_LEN)); // sync-init, return value is number of files int32_t nfiles; nfiles = syncInit(cfd, &tbytes); if (nfiles == -1) return -1; errMsg(LOG_INFO, "Number of files to synchronize: %d", nfiles); // outer loop: files, inner loop: chunks for (int i = 0; i < nfiles; i++) { FileChunk *chunk; int fd = -1; // we are guaranteed to get at least one chunk for each file chunk = (FileChunk *) recvMessage(cfd, FileChunkType, &tbytes); if (chunk == NULL) { errMsg(LOG_ERR, "Could not read message from client."); return -1; } for (;;) { for (int k = 0; k < chunk->n_ops; k++) { // TODO // in case of a failure inform client to do an rsync based sync handleGenericOperation(&fd, chunk->relative_path, chunk->ops[k]); } if (chunk->last_chunk == 1) { file_chunk__free_unpacked(chunk, NULL); break; } else { file_chunk__free_unpacked(chunk, NULL); chunk = (FileChunk *) recvMessage(cfd, FileChunkType, &tbytes); if (chunk == NULL) { errMsg(LOG_ERR, "Could not read message from client."); return -1; } } } if (fd != -1) { if (close(fd) == -1) errMsg(LOG_WARNING, "Could not close file."); } } errMsg(LOG_INFO, "Received bytes: %lld", tbytes); // transfer was successful, we can delete snapshot (created in syncInit()) if (deleteSnapshot(config.snapshot) == -1) { errMsg(LOG_ERR, "Could not delete snapshot %s", config.snapshot); close(cfd); return -1; } // rename resource.syncid to resource.syncid.last char lastsyncidpath[PATH_MAX]; char syncidpath[PATH_MAX]; snprintf(lastsyncidpath, PATH_MAX, "%s/%s.syncid.last", config.logdir, config.resource); snprintf(syncidpath, PATH_MAX, "%s/%s.syncid", config.logdir, config.resource); if (rename(syncidpath, lastsyncidpath) == -1) { errnoMsg(LOG_CRIT, "Could not rename sync-id file to sync-id.last."); close(cfd); return -1; } // and finally send confirmation to client SyncFinish conf = SYNC_FINISH__INIT; conf.has_transferred_bytes = 1; conf.transferred_bytes = (uint64_t) tbytes; if (sendMessage(cfd, SyncFinishType, &conf) != 0) { close(cfd); return -1; } if (close(cfd) == -1) errMsg(LOG_WARNING, "Could not close socket."); return 0; }