xref: /mOS-networking-stack/util/netlib.c (revision 76404edc)
1*76404edcSAsim Jamshed #define _GNU_SOURCE
2*76404edcSAsim Jamshed #include <sched.h>
3*76404edcSAsim Jamshed #include <unistd.h>
4*76404edcSAsim Jamshed #include <sys/types.h>
5*76404edcSAsim Jamshed #include <sys/socket.h>
6*76404edcSAsim Jamshed #include <netinet/in.h>
7*76404edcSAsim Jamshed #include <arpa/inet.h>
8*76404edcSAsim Jamshed #include <stdlib.h>
9*76404edcSAsim Jamshed #include <errno.h>
10*76404edcSAsim Jamshed #include <fcntl.h>
11*76404edcSAsim Jamshed #include <string.h>
12*76404edcSAsim Jamshed #include <stdio.h>
13*76404edcSAsim Jamshed #include <netdb.h>
14*76404edcSAsim Jamshed #include <ctype.h>
15*76404edcSAsim Jamshed 
16*76404edcSAsim Jamshed #include "netlib.h"
17*76404edcSAsim Jamshed 
18*76404edcSAsim Jamshed /*----------------------------------------------------------------------------*/
19*76404edcSAsim Jamshed int
GetNumCPUCores(void)20*76404edcSAsim Jamshed GetNumCPUCores(void)
21*76404edcSAsim Jamshed {
22*76404edcSAsim Jamshed 	return (int)sysconf(_SC_NPROCESSORS_ONLN);
23*76404edcSAsim Jamshed }
24*76404edcSAsim Jamshed /*----------------------------------------------------------------------------*/
25*76404edcSAsim Jamshed int
AffinitizeThreadToCore(int core)26*76404edcSAsim Jamshed AffinitizeThreadToCore(int core)
27*76404edcSAsim Jamshed {
28*76404edcSAsim Jamshed 	cpu_set_t *cmask;
29*76404edcSAsim Jamshed 	int n, ret;
30*76404edcSAsim Jamshed 
31*76404edcSAsim Jamshed     n = sysconf(_SC_NPROCESSORS_ONLN);
32*76404edcSAsim Jamshed 
33*76404edcSAsim Jamshed 	if (core < 0 || core >= n) {
34*76404edcSAsim Jamshed 		fprintf(stderr, "%d: invalid CPU number.\n", core);
35*76404edcSAsim Jamshed 		return -1;
36*76404edcSAsim Jamshed 	}
37*76404edcSAsim Jamshed 
38*76404edcSAsim Jamshed 	cmask = CPU_ALLOC(n);
39*76404edcSAsim Jamshed 	if (cmask == NULL) {
40*76404edcSAsim Jamshed 		fprintf(stderr, "%d: uexpected cmask.\n", n);
41*76404edcSAsim Jamshed 		return -1;
42*76404edcSAsim Jamshed 	}
43*76404edcSAsim Jamshed 
44*76404edcSAsim Jamshed 	CPU_ZERO_S(n, cmask);
45*76404edcSAsim Jamshed 	CPU_SET_S(core, n, cmask);
46*76404edcSAsim Jamshed 
47*76404edcSAsim Jamshed 	ret = sched_setaffinity(0, n, cmask);
48*76404edcSAsim Jamshed 
49*76404edcSAsim Jamshed 	CPU_FREE(cmask);
50*76404edcSAsim Jamshed 	return ret;
51*76404edcSAsim Jamshed }
52*76404edcSAsim Jamshed /*----------------------------------------------------------------------------*/
53*76404edcSAsim Jamshed int
CreateServerSocket(int port,int isNonBlocking)54*76404edcSAsim Jamshed CreateServerSocket(int port, int isNonBlocking)
55*76404edcSAsim Jamshed {
56*76404edcSAsim Jamshed 	int s;
57*76404edcSAsim Jamshed 	struct sockaddr_in addr;
58*76404edcSAsim Jamshed 	struct linger doLinger;
59*76404edcSAsim Jamshed 	int doReuse = 1;
60*76404edcSAsim Jamshed 
61*76404edcSAsim Jamshed 	if ((s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
62*76404edcSAsim Jamshed 		fprintf(stderr, "socket() failed, errno=%d msg=%s\n",
63*76404edcSAsim Jamshed 				errno, strerror(errno));
64*76404edcSAsim Jamshed 		return(-1);
65*76404edcSAsim Jamshed 	}
66*76404edcSAsim Jamshed 
67*76404edcSAsim Jamshed 	/* don't linger on close */
68*76404edcSAsim Jamshed 	doLinger.l_onoff = doLinger.l_linger = 0;
69*76404edcSAsim Jamshed 	if (setsockopt(s, SOL_SOCKET, SO_LINGER,
70*76404edcSAsim Jamshed 				   &doLinger, sizeof(doLinger)) == -1) {
71*76404edcSAsim Jamshed 		close(s);
72*76404edcSAsim Jamshed 		return(-1);
73*76404edcSAsim Jamshed 	}
74*76404edcSAsim Jamshed 
75*76404edcSAsim Jamshed 	/* reuse addresses */
76*76404edcSAsim Jamshed 	if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
77*76404edcSAsim Jamshed 				   &doReuse, sizeof(doReuse)) == -1) {
78*76404edcSAsim Jamshed 		close(s);
79*76404edcSAsim Jamshed 		return(-1);
80*76404edcSAsim Jamshed 	}
81*76404edcSAsim Jamshed 
82*76404edcSAsim Jamshed 	/* make the listening socket nonblocking */
83*76404edcSAsim Jamshed 	if (isNonBlocking) {
84*76404edcSAsim Jamshed 		if (fcntl(s, F_SETFL, O_NDELAY) < 0) {
85*76404edcSAsim Jamshed 			fprintf(stderr, "fcntl() failed, errno=%d msg=%s\n",
86*76404edcSAsim Jamshed 					errno, strerror(errno));
87*76404edcSAsim Jamshed 			close(s);
88*76404edcSAsim Jamshed 			return(-1);
89*76404edcSAsim Jamshed 		}
90*76404edcSAsim Jamshed 	}
91*76404edcSAsim Jamshed 
92*76404edcSAsim Jamshed 	memset(&addr, 0, sizeof(addr));
93*76404edcSAsim Jamshed 	addr.sin_family = AF_INET;
94*76404edcSAsim Jamshed 	addr.sin_addr.s_addr = htonl(INADDR_ANY);
95*76404edcSAsim Jamshed 	addr.sin_port = htons(port);
96*76404edcSAsim Jamshed 	if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
97*76404edcSAsim Jamshed 		fprintf(stderr, "bind() failed, errno=%d msg=%s\n",
98*76404edcSAsim Jamshed 				errno, strerror(errno));
99*76404edcSAsim Jamshed 		close(s);
100*76404edcSAsim Jamshed 		return(-1);
101*76404edcSAsim Jamshed 	}
102*76404edcSAsim Jamshed 
103*76404edcSAsim Jamshed 	if (listen(s, 1024) < 0) {
104*76404edcSAsim Jamshed 		close(s);
105*76404edcSAsim Jamshed 		return(-1);
106*76404edcSAsim Jamshed 	}
107*76404edcSAsim Jamshed 
108*76404edcSAsim Jamshed 	return(s);
109*76404edcSAsim Jamshed }
110*76404edcSAsim Jamshed /*-------------------------------------------------------------------------*/
111*76404edcSAsim Jamshed int
CreateConnectionSocket(in_addr_t netAddr,int portNum,int nonBlocking)112*76404edcSAsim Jamshed CreateConnectionSocket(in_addr_t netAddr, int portNum, int nonBlocking)
113*76404edcSAsim Jamshed {
114*76404edcSAsim Jamshed   struct sockaddr_in saddr;
115*76404edcSAsim Jamshed   int fd;
116*76404edcSAsim Jamshed   struct linger doLinger;
117*76404edcSAsim Jamshed   int doReuse = 1;
118*76404edcSAsim Jamshed 
119*76404edcSAsim Jamshed   if ((fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
120*76404edcSAsim Jamshed       fprintf(stderr, "failed creating socket - %d\n", errno);
121*76404edcSAsim Jamshed 	  return(-1);
122*76404edcSAsim Jamshed   }
123*76404edcSAsim Jamshed 
124*76404edcSAsim Jamshed   /* don't linger on close */
125*76404edcSAsim Jamshed   doLinger.l_onoff = doLinger.l_linger = 0;
126*76404edcSAsim Jamshed   if (setsockopt(fd, SOL_SOCKET, SO_LINGER,
127*76404edcSAsim Jamshed 				 &doLinger, sizeof(doLinger)) == -1) {
128*76404edcSAsim Jamshed 	  close(fd);
129*76404edcSAsim Jamshed 	  return(-1);
130*76404edcSAsim Jamshed   }
131*76404edcSAsim Jamshed 
132*76404edcSAsim Jamshed   /* reuse addresses */
133*76404edcSAsim Jamshed   if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
134*76404edcSAsim Jamshed 				 &doReuse, sizeof(doReuse)) == -1) {
135*76404edcSAsim Jamshed 	  close(fd);
136*76404edcSAsim Jamshed 	  return(-1);
137*76404edcSAsim Jamshed   }
138*76404edcSAsim Jamshed 
139*76404edcSAsim Jamshed   if (nonBlocking) {
140*76404edcSAsim Jamshed     if (fcntl(fd, F_SETFL, O_NDELAY) < 0) {
141*76404edcSAsim Jamshed 		fprintf(stderr, "failed fcntl'ing socket - %d\n", errno);
142*76404edcSAsim Jamshed 		close(fd);
143*76404edcSAsim Jamshed 		return(-1);
144*76404edcSAsim Jamshed     }
145*76404edcSAsim Jamshed   }
146*76404edcSAsim Jamshed 
147*76404edcSAsim Jamshed   saddr.sin_family = AF_INET;
148*76404edcSAsim Jamshed   saddr.sin_addr.s_addr = netAddr;
149*76404edcSAsim Jamshed   saddr.sin_port = htons(portNum);
150*76404edcSAsim Jamshed 
151*76404edcSAsim Jamshed   if (connect(fd, (struct sockaddr *) &saddr,
152*76404edcSAsim Jamshed 			  sizeof(struct sockaddr_in)) < 0) {
153*76404edcSAsim Jamshed     if (errno == EINPROGRESS)
154*76404edcSAsim Jamshed 		return(fd);
155*76404edcSAsim Jamshed 	fprintf(stderr, "failed connecting socket addr=%s port %d - errno %d\n",
156*76404edcSAsim Jamshed 			inet_ntoa(saddr.sin_addr), portNum, errno);
157*76404edcSAsim Jamshed     close(fd);
158*76404edcSAsim Jamshed     return(-1);
159*76404edcSAsim Jamshed   }
160*76404edcSAsim Jamshed 
161*76404edcSAsim Jamshed   return(fd);
162*76404edcSAsim Jamshed }
163*76404edcSAsim Jamshed /*----------------------------------------------------------------------------*/
164*76404edcSAsim Jamshed void
ParseOptions(int argc,const char ** argv,struct Options * ops)165*76404edcSAsim Jamshed ParseOptions(int argc, const char** argv, struct Options* ops)
166*76404edcSAsim Jamshed {
167*76404edcSAsim Jamshed 	int i, j;
168*76404edcSAsim Jamshed 
169*76404edcSAsim Jamshed 	for (i = 1; i < argc; i++) {
170*76404edcSAsim Jamshed 		for (j = 0; ops[j].op_name; j++) {
171*76404edcSAsim Jamshed 			if (strcmp(ops[j].op_name, argv[i]) == 0) {
172*76404edcSAsim Jamshed 				if (i + 1 >= argc) {
173*76404edcSAsim Jamshed 					fprintf(stderr, "no value provided for %s option\n",
174*76404edcSAsim Jamshed 							argv[i]);
175*76404edcSAsim Jamshed 					exit(-1);
176*76404edcSAsim Jamshed 				}
177*76404edcSAsim Jamshed 				*(ops[j].op_varptr) = (char *)argv[++i];
178*76404edcSAsim Jamshed 				break;
179*76404edcSAsim Jamshed 			}
180*76404edcSAsim Jamshed 		}
181*76404edcSAsim Jamshed 		if (ops[j].op_name == NULL) {
182*76404edcSAsim Jamshed 			fprintf(stderr, "option %s is not supported\n", argv[i]);
183*76404edcSAsim Jamshed 			exit(-1);
184*76404edcSAsim Jamshed 		}
185*76404edcSAsim Jamshed 	}
186*76404edcSAsim Jamshed }
187*76404edcSAsim Jamshed /*----------------------------------------------------------------------------*/
188*76404edcSAsim Jamshed void
PrintOptions(const struct Options * ops,int printVal)189*76404edcSAsim Jamshed PrintOptions(const struct Options* ops, int printVal)
190*76404edcSAsim Jamshed {
191*76404edcSAsim Jamshed 	int i;
192*76404edcSAsim Jamshed 
193*76404edcSAsim Jamshed 	if (printVal) {
194*76404edcSAsim Jamshed 		/* for printing option values */
195*76404edcSAsim Jamshed 		printf("The value for each option is as follows:\n");
196*76404edcSAsim Jamshed 	} else {
197*76404edcSAsim Jamshed 		/* for explaining the options */
198*76404edcSAsim Jamshed 		printf("Here is the list of allowable options:\n");
199*76404edcSAsim Jamshed 	}
200*76404edcSAsim Jamshed 	for (i = 0; ops[i].op_name; i++) {
201*76404edcSAsim Jamshed 		printf("%s: %s\n",
202*76404edcSAsim Jamshed 			   ops[i].op_name, printVal? *ops[i].op_varptr:ops[i].op_comment);
203*76404edcSAsim Jamshed 	}
204*76404edcSAsim Jamshed }
205*76404edcSAsim Jamshed /*----------------------------------------------------------------------------*/
206*76404edcSAsim Jamshed char *
GetHeaderString(const char * buf,const char * header,int hdrsize)207*76404edcSAsim Jamshed GetHeaderString(const char *buf, const char* header, int hdrsize)
208*76404edcSAsim Jamshed {
209*76404edcSAsim Jamshed #define SKIP_SPACE(x) while ((*(x)) && isspace((*(x)))) (x)++;
210*76404edcSAsim Jamshed 	char *temp = strstr(buf, header);
211*76404edcSAsim Jamshed 
212*76404edcSAsim Jamshed 	if (temp) {
213*76404edcSAsim Jamshed 		temp += hdrsize;
214*76404edcSAsim Jamshed 		SKIP_SPACE(temp);
215*76404edcSAsim Jamshed 		if (*temp)
216*76404edcSAsim Jamshed 			return (temp);
217*76404edcSAsim Jamshed 	}
218*76404edcSAsim Jamshed 	return (NULL);
219*76404edcSAsim Jamshed }
220*76404edcSAsim Jamshed /*----------------------------------------------------------------------------*/
221*76404edcSAsim Jamshed int
GetHeaderLong(const char * buf,const char * header,int hdrsize,long int * val)222*76404edcSAsim Jamshed GetHeaderLong(const char* buf, const char* header, int hdrsize, long int *val)
223*76404edcSAsim Jamshed {
224*76404edcSAsim Jamshed 	long int temp_val;
225*76404edcSAsim Jamshed 	char *temp;
226*76404edcSAsim Jamshed 
227*76404edcSAsim Jamshed 	if ((temp = GetHeaderString(buf, header, hdrsize)) != NULL) {
228*76404edcSAsim Jamshed 		temp_val = strtol(temp, NULL, 10);
229*76404edcSAsim Jamshed 		if (errno != ERANGE && errno != EINVAL) {
230*76404edcSAsim Jamshed 			*val = temp_val;
231*76404edcSAsim Jamshed 			return (TRUE);
232*76404edcSAsim Jamshed 		}
233*76404edcSAsim Jamshed 	}
234*76404edcSAsim Jamshed 	return (FALSE);
235*76404edcSAsim Jamshed }
236