#define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include #include #include "netlib.h" /*----------------------------------------------------------------------------*/ int GetNumCPUCores(void) { return (int)sysconf(_SC_NPROCESSORS_ONLN); } /*----------------------------------------------------------------------------*/ int AffinitizeThreadToCore(int core) { cpu_set_t *cmask; int n, ret; n = sysconf(_SC_NPROCESSORS_ONLN); if (core < 0 || core >= n) { fprintf(stderr, "%d: invalid CPU number.\n", core); return -1; } cmask = CPU_ALLOC(n); if (cmask == NULL) { fprintf(stderr, "%d: uexpected cmask.\n", n); return -1; } CPU_ZERO_S(n, cmask); CPU_SET_S(core, n, cmask); ret = sched_setaffinity(0, n, cmask); CPU_FREE(cmask); return ret; } /*----------------------------------------------------------------------------*/ int CreateServerSocket(int port, int isNonBlocking) { int s; struct sockaddr_in addr; struct linger doLinger; int doReuse = 1; if ((s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { fprintf(stderr, "socket() failed, errno=%d msg=%s\n", errno, strerror(errno)); return(-1); } /* don't linger on close */ doLinger.l_onoff = doLinger.l_linger = 0; if (setsockopt(s, SOL_SOCKET, SO_LINGER, &doLinger, sizeof(doLinger)) == -1) { close(s); return(-1); } /* reuse addresses */ if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &doReuse, sizeof(doReuse)) == -1) { close(s); return(-1); } /* make the listening socket nonblocking */ if (isNonBlocking) { if (fcntl(s, F_SETFL, O_NDELAY) < 0) { fprintf(stderr, "fcntl() failed, errno=%d msg=%s\n", errno, strerror(errno)); close(s); return(-1); } } memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_addr.s_addr = htonl(INADDR_ANY); addr.sin_port = htons(port); if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) { fprintf(stderr, "bind() failed, errno=%d msg=%s\n", errno, strerror(errno)); close(s); return(-1); } if (listen(s, 1024) < 0) { close(s); return(-1); } return(s); } /*-------------------------------------------------------------------------*/ int CreateConnectionSocket(in_addr_t netAddr, int portNum, int nonBlocking) { struct sockaddr_in saddr; int fd; struct linger doLinger; int doReuse = 1; if ((fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { fprintf(stderr, "failed creating socket - %d\n", errno); return(-1); } /* don't linger on close */ doLinger.l_onoff = doLinger.l_linger = 0; if (setsockopt(fd, SOL_SOCKET, SO_LINGER, &doLinger, sizeof(doLinger)) == -1) { close(fd); return(-1); } /* reuse addresses */ if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &doReuse, sizeof(doReuse)) == -1) { close(fd); return(-1); } if (nonBlocking) { if (fcntl(fd, F_SETFL, O_NDELAY) < 0) { fprintf(stderr, "failed fcntl'ing socket - %d\n", errno); close(fd); return(-1); } } saddr.sin_family = AF_INET; saddr.sin_addr.s_addr = netAddr; saddr.sin_port = htons(portNum); if (connect(fd, (struct sockaddr *) &saddr, sizeof(struct sockaddr_in)) < 0) { if (errno == EINPROGRESS) return(fd); fprintf(stderr, "failed connecting socket addr=%s port %d - errno %d\n", inet_ntoa(saddr.sin_addr), portNum, errno); close(fd); return(-1); } return(fd); } /*----------------------------------------------------------------------------*/ void ParseOptions(int argc, const char** argv, struct Options* ops) { int i, j; for (i = 1; i < argc; i++) { for (j = 0; ops[j].op_name; j++) { if (strcmp(ops[j].op_name, argv[i]) == 0) { if (i + 1 >= argc) { fprintf(stderr, "no value provided for %s option\n", argv[i]); exit(-1); } *(ops[j].op_varptr) = (char *)argv[++i]; break; } } if (ops[j].op_name == NULL) { fprintf(stderr, "option %s is not supported\n", argv[i]); exit(-1); } } } /*----------------------------------------------------------------------------*/ void PrintOptions(const struct Options* ops, int printVal) { int i; if (printVal) { /* for printing option values */ printf("The value for each option is as follows:\n"); } else { /* for explaining the options */ printf("Here is the list of allowable options:\n"); } for (i = 0; ops[i].op_name; i++) { printf("%s: %s\n", ops[i].op_name, printVal? *ops[i].op_varptr:ops[i].op_comment); } } /*----------------------------------------------------------------------------*/ char * GetHeaderString(const char *buf, const char* header, int hdrsize) { #define SKIP_SPACE(x) while ((*(x)) && isspace((*(x)))) (x)++; char *temp = strstr(buf, header); if (temp) { temp += hdrsize; SKIP_SPACE(temp); if (*temp) return (temp); } return (NULL); } /*----------------------------------------------------------------------------*/ int GetHeaderLong(const char* buf, const char* header, int hdrsize, long int *val) { long int temp_val; char *temp; if ((temp = GetHeaderString(buf, header, hdrsize)) != NULL) { temp_val = strtol(temp, NULL, 10); if (errno != ERANGE && errno != EINVAL) { *val = temp_val; return (TRUE); } } return (FALSE); }