blob: 8e3292cf2178f850250b55f396ca3dd9b297f4b0 [file] [log] [blame]
lh9ed821d2023-04-07 01:36:19 -07001#include <errno.h>
2#include <fcntl.h>
3#include <string.h>
4#include <stdlib.h>
5#include "uemf.h"
6#include "softap_log.h"
7
8extern socket_t **socketList;
9extern int socketMax;
10extern int socketHighestFd;
11static int socketOpenCount = 0;
12
13static void socketAccept(socket_t *sp);
14static int socketDoEvent(socket_t *sp);
15static int tryAlternateConnect(int sock, struct sockaddr *sockaddr);
16
17int socketOpen()
18{
19 if (++socketOpenCount > 1) {
20 return 0;
21 }
22 socketList = NULL;
23 socketMax = 0;
24 socketHighestFd = -1;
25
26 return 0;
27}
28
29int socketWaitForEvent(socket_t *sp, int handlerMask, int *errCode)
30{
31 int mask;
32
33 a_assert(sp);
34
35 mask = sp->handlerMask;
36 sp->handlerMask |= handlerMask;
37 while (socketSelect(sp->sid, 1000)) {
38 if (sp->currentEvents & (handlerMask | SOCKET_EXCEPTION)) {
39 break;
40 }
41 }
42 sp->handlerMask = mask;
43 if (sp->currentEvents & SOCKET_EXCEPTION) {
44 return -1;
45 } else if (sp->currentEvents & handlerMask) {
46 return 1;
47 }
48 if (errCode) {
49 *errCode = errno = EWOULDBLOCK;
50 }
51 return 0;
52}
53
54void socketClose()
55{
56 int i;
57
58 if (--socketOpenCount <= 0) {
59 for (i = socketMax; i >= 0; i--) {
60 if (socketList && socketList[i]) {
61 socketCloseConnection(i);
62 }
63 }
64 socketOpenCount = 0;
65 }
66}
67
68int socketOpenConnection6(char *host, int port, socketAccept_t accept, int flags)
69{
70 socket_t *sp;
71 struct sockaddr_in6 sockaddr;
72 int sid, dgram, rc;
73 if (port > SOCKET_PORT_MAX) {
74 return -1;
75 }
76 if ((sid = socketAlloc(NULL, port, accept, flags)) < 0) {
77 return -1;
78 }
79 sp = socketList[sid];
80 a_assert(sp);
81 memset((char *) &sockaddr, '\0', sizeof(struct sockaddr_in6));
82 sockaddr.sin6_family = AF_INET6;
83 sockaddr.sin6_port = htons((short) (port & 0xFFFF));
84 dgram = sp->flags & SOCKET_DATAGRAM;
85 sp->sock = socket(AF_INET6, dgram ? SOCK_DGRAM: SOCK_STREAM, 0);
86 if (sp->sock < 0) {
87 socketFree(sid);
88 return -1;
89 }
90 if(fcntl(sp->sock, F_SETFD, FD_CLOEXEC) < 0)
91 {
92 slog(MISC_PRINT,SLOG_ERR, "fcntl return -1.\n");
93 }
94
95 socketHighestFd = max(socketHighestFd, sp->sock);
96 rc = 1;
97 // cov 3 CHECKED_RETURN
98 if(setsockopt(sp->sock, SOL_SOCKET, SO_REUSEADDR, (char *)&rc, sizeof(rc)) < 0){
99 ;
100 }
101 if (bind(sp->sock, (struct sockaddr *) &sockaddr,
102 sizeof(sockaddr)) < 0) {
103 socketFree(sid);
104 return -1;
105 }
106
107 if (! dgram) {
108 if (listen(sp->sock, SOMAXCONN) < 0) {
109 socketFree(sid);
110 return -1;
111 }
112
113 sp->flags |= SOCKET_LISTENING;
114 }
115 sp->handlerMask |= SOCKET_READABLE;
116
117 if (flags & SOCKET_BLOCK) {
118 socketSetBlock(sid, 1);
119 } else {
120 socketSetBlock(sid, 0);
121 }
122 return sid;
123}
124
125void socketCloseConnection(int sid)
126{
127 socket_t *sp;
128
129 if ((sp = socketPtr(sid)) == NULL) {
130 return;
131 }
132 socketFree(sid);
133}
134
135static void socketAccept(socket_t *sp)
136{
137 struct sockaddr_in6 addr;
138 //socket_t *nsp;
139 size_t len;
140 char pString[40]={0};
141 int newSock, nid;
142
143 a_assert(sp);
144 len = sizeof(struct sockaddr_in6);
145 if ((newSock = accept(sp->sock, (struct sockaddr *) &addr, (int *) &len)) < 0) {
146 return;
147 }
148 if(fcntl(newSock, F_SETFD, FD_CLOEXEC) < 0)
149 {
150 slog(MISC_PRINT,SLOG_ERR, "fcntl return -1.\n");
151 }
152 socketHighestFd = max(socketHighestFd, newSock);
153
154 nid = socketAlloc(sp->host, sp->port, sp->accept, sp->flags);
155 //nsp = socketList[nid];
156 a_assert(socketList[nid]);
157 if (socketList[nid] == NULL) {
158 close(newSock);
159 return;
160 }
161 socketList[nid]->sock = newSock;
162 socketList[nid]->flags &= ~SOCKET_LISTENING;
163
164 socketSetBlock(nid, (socketList[nid]->flags & SOCKET_BLOCK) ? 1: 0);
165
166 if (sp->accept != NULL) {
167 //pString = inet_ntoa(addr);
168 if(addr.sin6_addr.s6_addr32[0] == 0
169 && addr.sin6_addr.s6_addr32[1] == 0
170 && addr.sin6_addr.s6_addr32[2] == 0xffff0000)
171 inet_ntop(AF_INET,(void*)&addr.sin6_addr.s6_addr32[3],pString,sizeof(pString));
172 else
173 inet_ntop(AF_INET6,(void*)&addr.sin6_addr,pString,sizeof(pString));
174 if ((sp->accept)(nid, pString, ntohs(addr.sin6_port), sp->sid) < 0) {
175 socketFree(nid);
176 }
177 }
178 else
179 socketFree(nid);
180}
181
182int socketGetInput(int sid, char *buf, int toRead, int *errCode)
183{
184 struct sockaddr_in server;
185 socket_t *sp;
186 int len, bytesRead;
187 static int s_ErrorCnt = 0;
188 a_assert(buf);
189 a_assert(errCode);
190
191 *errCode = 0;
192
193 if ((sp = socketPtr(sid)) == NULL) {
194 return -1;
195 }
196
197 if (sp->flags & SOCKET_EOF) {
198 return 0;
199 }
200 if (sp->flags & SOCKET_DATAGRAM) {
201 len = sizeof(server);
202 bytesRead = recvfrom(sp->sock, buf, toRead, 0,
203 (struct sockaddr *) &server, &len);
204 } else {
205 bytesRead = recv(sp->sock, buf, toRead, 0);
206 }
207
208 if (bytesRead < 0)
209 {
210 *errCode = socketGetError();
211 //printf("\n socketGetInput ERROR: bytesRead = %d, *errCode = %d! ", bytesRead, *errCode);
212 if (*errCode == ECONNRESET || s_ErrorCnt++ > 500)
213 {
214 sp->flags |= SOCKET_CONNRESET;
215 return 0;
216 }
217 return -1;
218 }
219 else
220 {
221 s_ErrorCnt = 0;
222 }
223 return bytesRead;
224}
225
226void socketRegisterInterest(socket_t *sp, int handlerMask)
227{
228 a_assert(sp);
229
230 sp->handlerMask = handlerMask;
231}
232
233int socketReady(int sid)
234{
235 socket_t *sp;
236 int all;
237
238 all = 0;
239 if (sid < 0) {
240 sid = 0;
241 all = 1;
242 }
243
244 for (; sid < socketMax; sid++) {
245 if ((sp = socketList[sid]) == NULL) {
246 if (! all) {
247 break;
248 } else {
249 continue;
250 }
251 }
252 if (sp->flags & SOCKET_CONNRESET) {
253 socketCloseConnection(sid);
254 return 0;
255 }
256 if (sp->currentEvents & sp->handlerMask) {
257 return 1;
258 }
259
260 if (sp->handlerMask & SOCKET_READABLE && socketInputBuffered(sid) > 0) {
261 socketSelect(sid, 0);
262 return 1;
263 }
264 if (! all) {
265 break;
266 }
267 }
268 return 0;
269}
270
271int socketSelect(int sid, int timeout)
272{
273 socket_t *sp;
274 struct timeval tv;
275 fd_mask *readFds, *writeFds, *exceptFds;
276 int all, len, nwords, index, bit, nEvents;
277
278 nwords = (socketHighestFd + NFDBITS) / NFDBITS;
279 len = nwords * sizeof(int);
280
281 readFds = balloc(B_L, len);
282 if(readFds == NULL)
283 return 0;
284 memset(readFds, 0, len);
285 writeFds = balloc(B_L, len);
286 if(writeFds == NULL){
287 bfree(B_L, readFds);
288 return 0;
289 }
290 memset(writeFds, 0, len);
291 exceptFds = balloc(B_L, len);
292 if(exceptFds == NULL){
293 bfree(B_L, readFds);
294 bfree(B_L, writeFds);
295 return 0;
296 }
297 memset(exceptFds, 0, len);
298
299 tv.tv_sec = timeout / 1000;
300 tv.tv_usec = (timeout % 1000) * 1000;
301
302 all = nEvents = 0;
303
304 if (sid < 0) {
305 all++;
306 sid = 0;
307 }
308
309 for (; sid < socketMax; sid++) {
310 if ((sp = socketList[sid]) == NULL) {
311 if (all == 0) {
312 break;
313 } else {
314 continue;
315 }
316 }
317 a_assert(sp);
318
319 index = sp->sock / (NBBY * sizeof(fd_mask));
320 bit = 1 << (sp->sock % (NBBY * sizeof(fd_mask)));
321
322 if (sp->handlerMask & SOCKET_READABLE) {
323 readFds[index] |= bit;
324 nEvents++;
325 if (socketInputBuffered(sid) > 0) {
326 tv.tv_sec = 0;
327 tv.tv_usec = 0;
328 }
329 }
330 if (sp->handlerMask & SOCKET_WRITABLE) {
331 writeFds[index] |= bit;
332 nEvents++;
333 }
334 if (sp->handlerMask & SOCKET_EXCEPTION) {
335 exceptFds[index] |= bit;
336 nEvents++;
337 }
338 if (! all) {
339 break;
340 }
341 }
342
343 nEvents = select(socketHighestFd + 1, (fd_set *) readFds,
344 (fd_set *) writeFds, (fd_set *) exceptFds, &tv);
345
346 if (nEvents > 0) {
347 if (all) {
348 sid = 0;
349 }
350 for (; sid < socketMax; sid++) {
351 if ((sp = socketList[sid]) == NULL) {
352 if (all == 0) {
353 break;
354 } else {
355 continue;
356 }
357 }
358
359 index = sp->sock / (NBBY * sizeof(fd_mask));
360 bit = 1 << (sp->sock % (NBBY * sizeof(fd_mask)));
361
362 if (readFds[index] & bit || socketInputBuffered(sid) > 0) {
363 sp->currentEvents |= SOCKET_READABLE;
364 }
365 if (writeFds[index] & bit) {
366 sp->currentEvents |= SOCKET_WRITABLE;
367 }
368 if (exceptFds[index] & bit) {
369 sp->currentEvents |= SOCKET_EXCEPTION;
370 }
371 if (! all) {
372 break;
373 }
374 }
375 }
376
377 bfree(B_L, readFds);
378 bfree(B_L, writeFds);
379 bfree(B_L, exceptFds);
380
381 return nEvents;
382}
383
384void socketProcess(int sid)
385{
386 socket_t *sp;
387 int all;
388
389 all = 0;
390 if (sid < 0) {
391 all = 1;
392 sid = 0;
393 }
394 for (; sid < socketMax; sid++) {
395 if ((sp = socketList[sid]) == NULL) {
396 if (! all) {
397 break;
398 } else {
399 continue;
400 }
401 }
402 if (socketReady(sid)) {
403 socketDoEvent(sp);
404 }
405 if (! all) {
406 break;
407 }
408 }
409}
410
411static int socketDoEvent(socket_t *sp)
412{
413 ringq_t *rq;
414 int sid;
415
416 a_assert(sp);
417
418 sid = sp->sid;
419 if (sp->currentEvents & SOCKET_READABLE) {
420 if (sp->flags & SOCKET_LISTENING) {
421 socketAccept(sp);
422 sp->currentEvents = 0;
423 return 1;
424 }
425
426 } else {
427
428 if (sp->handlerMask & SOCKET_READABLE && socketInputBuffered(sid) > 0) {
429 sp->currentEvents |= SOCKET_READABLE;
430 }
431 }
432
433 if (sp->currentEvents & SOCKET_WRITABLE) {
434 if (sp->flags & SOCKET_FLUSHING) {
435 rq = &sp->outBuf;
436 if (ringqLen(rq) > 0) {
437 socketFlush(sp->sid);
438 } else {
439 sp->flags &= ~SOCKET_FLUSHING;
440 }
441 }
442 }
443
444 if (sp->handler && (sp->handlerMask & sp->currentEvents)) {
445 (sp->handler)(sid, sp->handlerMask & sp->currentEvents,
446 sp->handler_data);
447
448 if (socketList && sid < socketMax && socketList[sid] == sp) {
449 sp->currentEvents = 0;
450 }
451 }
452 return 1;
453}
454
455int socketSetBlock(int sid, int on)
456{
457 socket_t *sp;
458 unsigned long flag;
459 int iflag;
460 int oldBlock;
461 struct timeval rcv_timeo;
462
463 flag = iflag = !on;
464
465 if ((sp = socketPtr(sid)) == NULL) {
466 a_assert(0);
467 return 0;
468 }
469 oldBlock = (sp->flags & SOCKET_BLOCK);
470 sp->flags &= ~(SOCKET_BLOCK);
471 if (on) {
472 sp->flags |= SOCKET_BLOCK;
473 }
474
475
476 if (sp->flags & SOCKET_BLOCK) {
477
478 if(fcntl(sp->sock, F_SETFL, fcntl(sp->sock, F_GETFL) & ~O_NONBLOCK) < 0)
479 {
480 slog(MISC_PRINT,SLOG_ERR, "fcntl return -1.\n");
481 }
482
483 rcv_timeo.tv_sec = 60;
484 rcv_timeo.tv_usec = 0;
485 //printf("[zyl]set 60s send timeout\n");
486 //ÉèÖÃ60Ãë·¢Ëͳ¬Ê±
487 // cov 3 CHECKED_RETURN
488 if(setsockopt(sp->sock, SOL_SOCKET,SO_SNDTIMEO, (void*)&rcv_timeo, sizeof(rcv_timeo)) < 0){
489 ;
490 }
491 rcv_timeo.tv_sec = 1;
492 rcv_timeo.tv_usec = 0;
493
494 //ÉèÖÃ1Ãë½ÓÊÕ³¬Ê±
495 // cov 3 CHECKED_RETURN
496 if(setsockopt(sp->sock, SOL_SOCKET,SO_RCVTIMEO, (void*)&rcv_timeo, sizeof(rcv_timeo)) < 0){
497 ;
498 }
499
500 } else {
501 if(fcntl(sp->sock, F_SETFL, fcntl(sp->sock, F_GETFL) | O_NONBLOCK) < 0)
502 {
503 slog(MISC_PRINT,SLOG_ERR, "fcntl return -1.\n");
504 }
505 }
506 return oldBlock;
507}
508
509int socketSockBuffered(int sock)
510{
511 socket_t *sp;
512 int i;
513
514 for (i = 0; i < socketMax; i++) {
515 if ((sp = socketList[i]) == NULL || sp->sock != sock) {
516 continue;
517 }
518 return socketInputBuffered(i);
519 }
520 return 0;
521}
522