1 /*
2 * Copyright (c) 2006-2018, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2018-05-23 ChenYong First version
9 * 2018-11-12 ChenYong Add TLS support
10 */
11
12 #include <rtthread.h>
13 #include <rthw.h>
14
15 #include <sal_socket.h>
16 #include <sal_netdb.h>
17 #ifdef SAL_USING_TLS
18 #include <sal_tls.h>
19 #endif
20 #include <sal.h>
21
22 #define DBG_ENABLE
23 #define DBG_SECTION_NAME "SAL_SOC"
24 #define DBG_LEVEL DBG_INFO
25 #define DBG_COLOR
26 #include <rtdbg.h>
27
28 #define SOCKET_TABLE_STEP_LEN 4
29
30 /* the socket table used to dynamic allocate sockets */
31 struct sal_socket_table
32 {
33 uint32_t max_socket;
34 struct sal_socket **sockets;
35 };
36
37 #ifdef SAL_USING_TLS
38 /* The global TLS protocol options */
39 static struct sal_proto_tls *proto_tls;
40 #endif
41
42 /* The global array of available protocol families */
43 static struct sal_proto_family proto_families[SAL_PROTO_FAMILIES_NUM];
44 /* The global socket table */
45 static struct sal_socket_table socket_table;
46 static struct rt_mutex sal_core_lock;
47 static rt_bool_t init_ok = RT_FALSE;
48
49 #define IS_SOCKET_PROTO_TLS(sock) (((sock)->protocol == PROTOCOL_TLS) || \
50 ((sock)->protocol == PROTOCOL_DTLS))
51 #define SAL_SOCKOPS_PROTO_TLS_VALID(sock, name) (proto_tls && (proto_tls->ops->name) && IS_SOCKET_PROTO_TLS(sock))
52
53 #define SAL_SOCKOPT_PROTO_TLS_EXEC(sock, name, optval, optlen) \
54 do \
55 { \
56 if (SAL_SOCKOPS_PROTO_TLS_VALID(sock, name)) \
57 { \
58 return proto_tls->ops->name((sock)->user_data_tls, (optval), (optlen)); \
59 } \
60 }while(0) \
61
62
63 /**
64 * SAL (Socket Abstraction Layer) initialize.
65 *
66 * @return result 0: initialize success
67 * -1: initialize failed
68 */
sal_init(void)69 int sal_init(void)
70 {
71 int cn;
72
73 if (init_ok)
74 {
75 LOG_D("Socket Abstraction Layer is already initialized.");
76 return 0;
77 }
78
79 /* init sal socket table */
80 cn = SOCKET_TABLE_STEP_LEN < SAL_SOCKETS_NUM ? SOCKET_TABLE_STEP_LEN : SAL_SOCKETS_NUM;
81 socket_table.max_socket = cn;
82 socket_table.sockets = rt_calloc(1, cn * sizeof(struct sal_socket *));
83 if (socket_table.sockets == RT_NULL)
84 {
85 LOG_E("No memory for socket table.\n");
86 return -1;
87 }
88
89 /* create sal socket lock */
90 rt_mutex_init(&sal_core_lock, "sal_lock", RT_IPC_FLAG_FIFO);
91
92 LOG_I("Socket Abstraction Layer initialize success.");
93 init_ok = RT_TRUE;
94
95 return 0;
96 }
97 INIT_COMPONENT_EXPORT(sal_init);
98
99 /**
100 * This function will register TLS protocol to the global TLS protocol.
101 *
102 * @param pt TLS protocol object
103 *
104 * @return 0: TLS protocol object register success
105 */
106 #ifdef SAL_USING_TLS
sal_proto_tls_register(const struct sal_proto_tls * pt)107 int sal_proto_tls_register(const struct sal_proto_tls *pt)
108 {
109 RT_ASSERT(pt);
110 proto_tls = (struct sal_proto_tls *) pt;
111
112 return 0;
113 }
114 #endif
115
116 /**
117 * This function will register protocol family to the global array of protocol families.
118 *
119 * @param pf protocol family object
120 *
121 * @return 0: protocol family object register success
122 * -1: the global array of available protocol families is full
123 */
sal_proto_family_register(const struct sal_proto_family * pf)124 int sal_proto_family_register(const struct sal_proto_family *pf)
125 {
126 rt_base_t level;
127 int idx;
128
129 /* disable interrupt */
130 level = rt_hw_interrupt_disable();
131
132 /* check protocol family is already registered */
133 for(idx = 0; idx < SAL_PROTO_FAMILIES_NUM; idx++)
134 {
135 if (proto_families[idx].family == pf->family && proto_families[idx].create)
136 {
137 /* enable interrupt */
138 rt_hw_interrupt_enable(level);
139 LOG_E("%s protocol family is already registered!", pf->family);
140 return -1;
141 }
142 }
143
144 /* find an empty protocol family entry */
145 for(idx = 0; idx < SAL_PROTO_FAMILIES_NUM && proto_families[idx].create; idx++);
146
147 /* can't find an empty protocol family entry */
148 if (idx == SAL_PROTO_FAMILIES_NUM)
149 {
150 /* enable interrupt */
151 rt_hw_interrupt_enable(level);
152 return -1;
153 }
154
155 proto_families[idx].family = pf->family;
156 proto_families[idx].sec_family = pf->sec_family;
157 proto_families[idx].create = pf->create;
158
159 proto_families[idx].ops = pf->ops;
160 proto_families[idx].ops->gethostbyname = pf->ops->gethostbyname;
161 proto_families[idx].ops->gethostbyname_r = pf->ops->gethostbyname_r;
162 proto_families[idx].ops->freeaddrinfo = pf->ops->freeaddrinfo;
163 proto_families[idx].ops->getaddrinfo = pf->ops->getaddrinfo;
164
165 /* enable interrupt */
166 rt_hw_interrupt_enable(level);
167
168 return 0;
169 }
170
171 /**
172 * This function removes a previously registered protocol family object.
173 *
174 * @param pf protocol family object
175 *
176 * @return >=0 : unregister protocol family index
177 * -1 : unregister failed
178 */
sal_proto_family_unregister(int family)179 int sal_proto_family_unregister(int family)
180 {
181 int idx = 0;
182
183 RT_ASSERT(family > 0 && family < AF_MAX);
184
185 for(idx = 0; idx < SAL_PROTO_FAMILIES_NUM; idx++)
186 {
187 if (proto_families[idx].family == family && proto_families[idx].create)
188 {
189 rt_memset(&proto_families[idx], 0x00, sizeof(struct sal_proto_family));
190
191 return idx;
192 }
193 }
194
195 return -1;
196 }
197
198 /**
199 * This function will judge whether protocol family is registered
200 *
201 * @param family protocol family number
202 *
203 * @return 1: protocol family is registered
204 * 0: protocol family is not registered
205 */
sal_proto_family_is_registered(int family)206 rt_bool_t sal_proto_family_is_registered(int family)
207 {
208 int idx = 0;
209
210 RT_ASSERT(family > 0 && family < AF_MAX);
211
212 for (idx = 0; idx < SAL_PROTO_FAMILIES_NUM; idx++)
213 {
214 if (proto_families[idx].family == family && proto_families[idx].create)
215 {
216 return RT_TRUE;
217 }
218 }
219
220 return RT_FALSE;
221 }
222
223 /**
224 * This function will get protocol family object by family number.
225 *
226 * @param family protocol family number
227 *
228 * @return protocol family object
229 */
sal_proto_family_find(int family)230 struct sal_proto_family *sal_proto_family_find(int family)
231 {
232 int idx = 0;
233
234 RT_ASSERT(family > 0 && family < AF_MAX);
235
236 for (idx = 0; idx < SAL_PROTO_FAMILIES_NUM; idx++)
237 {
238 if (proto_families[idx].family == family && proto_families[idx].create)
239 {
240 return &proto_families[idx];
241 }
242 }
243
244 return RT_NULL;
245 }
246
247 /**
248 * This function will get sal socket object by sal socket descriptor.
249 *
250 * @param socket sal socket index
251 *
252 * @return sal socket object of the current sal socket index
253 */
sal_get_socket(int socket)254 struct sal_socket *sal_get_socket(int socket)
255 {
256 struct sal_socket_table *st = &socket_table;
257
258 if (socket < 0 || socket >= (int) st->max_socket)
259 {
260 return RT_NULL;
261 }
262
263 socket = socket - SAL_SOCKET_OFFSET;
264 /* check socket structure valid or not */
265 if (st->sockets[socket]->magic != SAL_SOCKET_MAGIC)
266 {
267 return RT_NULL;
268 }
269
270 return st->sockets[socket];
271 }
272
273 /**
274 * This function will lock sal socket.
275 *
276 * @note please don't invoke it on ISR.
277 */
sal_lock(void)278 static void sal_lock(void)
279 {
280 rt_err_t result;
281
282 result = rt_mutex_take(&sal_core_lock, RT_WAITING_FOREVER);
283 if (result != RT_EOK)
284 {
285 RT_ASSERT(0);
286 }
287 }
288
289 /**
290 * This function will lock sal socket.
291 *
292 * @note please don't invoke it on ISR.
293 */
sal_unlock(void)294 static void sal_unlock(void)
295 {
296 rt_mutex_release(&sal_core_lock);
297 }
298
299 /**
300 * This function will get protocol family structure by family type
301 *
302 * @param family protocol family
303 *
304 * @return protocol family structure address
305 */
get_proto_family(int family)306 static struct sal_proto_family *get_proto_family(int family)
307 {
308 int idx;
309
310 for (idx = 0; idx < SAL_PROTO_FAMILIES_NUM; idx++)
311 {
312 if (proto_families[idx].family == family && proto_families[idx].create)
313 {
314 return &proto_families[idx];
315 }
316 }
317 /* compare the secondary protocol families when primary protocol families find failed */
318 for (idx = 0; idx < SAL_PROTO_FAMILIES_NUM; idx++)
319 {
320 if (proto_families[idx].sec_family == family && proto_families[idx].create)
321 {
322 return &proto_families[idx];
323 }
324 }
325
326 return RT_NULL;
327 }
328
329 /**
330 * This function will initialize sal socket object and set socket options
331 *
332 * @param family protocol family
333 * @param type socket type
334 * @param protocol transfer Protocol
335 * @param res sal socket object address
336 *
337 * @return 0 : socket initialize success
338 * -1 : input the wrong family
339 * -2 : input the wrong socket type
340 * -3 : get protocol family object failed
341 * -4 : set socket options failed
342 */
socket_init(int family,int type,int protocol,struct sal_socket ** res)343 static int socket_init(int family, int type, int protocol, struct sal_socket **res)
344 {
345 struct sal_socket *sock;
346 struct sal_proto_family *pf;
347
348 if (family < 0 || family > AF_MAX)
349 {
350 return -1;
351 }
352
353 if (type < 0 || type > SOCK_MAX)
354 {
355 return -2;
356 }
357
358 sock = *res;
359 sock->domain = family;
360 sock->type = type;
361 sock->protocol = protocol;
362
363 /* get socket protocol family object */
364 if ((pf = get_proto_family(family)) == RT_NULL)
365 {
366 return -3;
367 }
368
369 /* registered the current socket options */
370 if (pf->create(sock, type, protocol) != 0)
371 {
372 return -4;
373 }
374
375 return 0;
376 }
377
socket_alloc(struct sal_socket_table * st,int f_socket)378 static int socket_alloc(struct sal_socket_table *st, int f_socket)
379 {
380 int idx;
381
382 /* find an empty socket entry */
383 for (idx = f_socket; idx < (int) st->max_socket; idx++)
384 {
385 if (st->sockets[idx] == RT_NULL)
386 break;
387 if (st->sockets[idx]->ops == RT_NULL)
388 break;
389 }
390
391 /* allocate a larger sockte container */
392 if (idx == (int) st->max_socket && st->max_socket < SAL_SOCKETS_NUM)
393 {
394 int cnt, index;
395 struct sal_socket **sockets;
396
397 /* increase the number of socket with 4 step length */
398 cnt = st->max_socket + SOCKET_TABLE_STEP_LEN;
399 cnt = cnt > SAL_SOCKETS_NUM ? SAL_SOCKETS_NUM : cnt;
400
401 sockets = rt_realloc(st->sockets, cnt * sizeof(struct sal_socket *));
402 if (sockets == RT_NULL)
403 goto __result; /* return st->max_socket */
404
405 /* clean the new allocated fds */
406 for (index = st->max_socket; index < cnt; index++)
407 {
408 sockets[index] = RT_NULL;
409 }
410
411 st->sockets = sockets;
412 st->max_socket = cnt;
413 }
414
415 /* allocate 'struct sal_socket' */
416 if (idx < (int) st->max_socket && st->sockets[idx] == RT_NULL)
417 {
418 st->sockets[idx] = rt_calloc(1, sizeof(struct sal_socket));
419 if (st->sockets[idx] == RT_NULL)
420 {
421 idx = st->max_socket;
422 }
423 }
424
425 __result:
426 return idx;
427
428 }
429
socket_new(void)430 static int socket_new(void)
431 {
432 struct sal_socket *sock;
433 struct sal_socket_table *st = &socket_table;
434 int idx;
435
436 sal_lock();
437
438 /* find an empty sal socket entry */
439 idx = socket_alloc(st, 0);
440
441 /* can't find an empty sal socket entry */
442 if (idx == (int) st->max_socket)
443 {
444 idx = -(1 + SAL_SOCKET_OFFSET);
445 goto __result;
446 }
447
448 sock = st->sockets[idx];
449 sock->socket = idx + SAL_SOCKET_OFFSET;
450 sock->magic = SAL_SOCKET_MAGIC;
451 sock->ops = RT_NULL;
452 sock->user_data = RT_NULL;
453 #ifdef SAL_USING_TLS
454 sock->user_data_tls = RT_NULL;
455 #endif
456
457 __result:
458 sal_unlock();
459 return idx + SAL_SOCKET_OFFSET;
460 }
461
sal_accept(int socket,struct sockaddr * addr,socklen_t * addrlen)462 int sal_accept(int socket, struct sockaddr *addr, socklen_t *addrlen)
463 {
464 int new_socket;
465 struct sal_socket *sock;
466
467 sock = sal_get_socket(socket);
468 if (!sock)
469 {
470 return -1;
471 }
472
473 if (sock->ops->accept == RT_NULL)
474 {
475 return -RT_ENOSYS;
476 }
477
478 new_socket = sock->ops->accept((int) sock->user_data, addr, addrlen);
479 if (new_socket != -1)
480 {
481 int retval;
482 int new_sal_socket;
483 struct sal_socket *new_sock;
484
485 /* allocate a new socket structure and registered socket options */
486 new_sal_socket = socket_new();
487 if (new_sal_socket < 0)
488 {
489 sock->ops->closesocket(new_socket);
490 return -1;
491 }
492 new_sock = sal_get_socket(new_sal_socket);
493
494 retval = socket_init(sock->domain, sock->type, sock->protocol, &new_sock);
495 if (retval < 0)
496 {
497 sock->ops->closesocket(new_socket);
498 rt_memset(new_sock, 0x00, sizeof(struct sal_socket));
499 LOG_E("New socket registered failed, return error %d.", retval);
500 return -1;
501 }
502
503 /* socket struct user_data used to store the acquired new socket */
504 new_sock->user_data = (void *) new_socket;
505
506 return new_sal_socket;
507 }
508
509 return -1;
510 }
511
sal_bind(int socket,const struct sockaddr * name,socklen_t namelen)512 int sal_bind(int socket, const struct sockaddr *name, socklen_t namelen)
513 {
514 struct sal_socket *sock;
515
516 sock = sal_get_socket(socket);
517 if (!sock)
518 {
519 return -1;
520 }
521
522 if (sock->ops->bind == RT_NULL)
523 {
524 return -RT_ENOSYS;
525 }
526
527 return sock->ops->bind((int) sock->user_data, name, namelen);
528 }
529
sal_shutdown(int socket,int how)530 int sal_shutdown(int socket, int how)
531 {
532 struct sal_socket *sock;
533
534 sock = sal_get_socket(socket);
535 if (!sock)
536 {
537 return -1;
538 }
539
540 if (sock->ops->shutdown == RT_NULL)
541 {
542 return -RT_ENOSYS;
543 }
544
545 if (sock->ops->shutdown((int) sock->user_data, how) == 0)
546 {
547 #ifdef SAL_USING_TLS
548 if (SAL_SOCKOPS_PROTO_TLS_VALID(sock, closesocket))
549 {
550 if (proto_tls->ops->closesocket(sock->user_data_tls) < 0)
551 {
552 return -1;
553 }
554 }
555 #endif
556 rt_free(sock);
557 socket_table.sockets[socket] = RT_NULL;
558 return 0;
559 }
560
561 return -1;
562 }
563
sal_getpeername(int socket,struct sockaddr * name,socklen_t * namelen)564 int sal_getpeername(int socket, struct sockaddr *name, socklen_t *namelen)
565 {
566 struct sal_socket *sock;
567
568 sock = sal_get_socket(socket);
569 if (!sock)
570 {
571 return -1;
572 }
573
574 if (sock->ops->getpeername == RT_NULL)
575 {
576 return -RT_ENOSYS;
577 }
578
579 return sock->ops->getpeername((int) sock->user_data, name, namelen);
580 }
581
sal_getsockname(int socket,struct sockaddr * name,socklen_t * namelen)582 int sal_getsockname(int socket, struct sockaddr *name, socklen_t *namelen)
583 {
584 struct sal_socket *sock;
585
586 sock = sal_get_socket(socket);
587 if (!sock)
588 {
589 return -1;
590 }
591
592 if (sock->ops->getsockname == RT_NULL)
593 {
594 return -RT_ENOSYS;
595 }
596
597 return sock->ops->getsockname((int) sock->user_data, name, namelen);
598 }
599
sal_getsockopt(int socket,int level,int optname,void * optval,socklen_t * optlen)600 int sal_getsockopt(int socket, int level, int optname, void *optval, socklen_t *optlen)
601 {
602 struct sal_socket *sock;
603
604 sock = sal_get_socket(socket);
605 if (!sock)
606 {
607 return -1;
608 }
609
610 if (sock->ops->getsockopt == RT_NULL)
611 {
612 return -RT_ENOSYS;
613 }
614
615 return sock->ops->getsockopt((int) sock->user_data, level, optname, optval, optlen);
616 }
617
sal_setsockopt(int socket,int level,int optname,const void * optval,socklen_t optlen)618 int sal_setsockopt(int socket, int level, int optname, const void *optval, socklen_t optlen)
619 {
620 struct sal_socket *sock;
621
622 sock = sal_get_socket(socket);
623 if (!sock)
624 {
625 return -1;
626 }
627
628 if (sock->ops->setsockopt == RT_NULL)
629 {
630 return -RT_ENOSYS;
631 }
632
633 #ifdef SAL_USING_TLS
634 if (level == SOL_TLS)
635 {
636 switch (optname)
637 {
638 case TLS_CRET_LIST:
639 SAL_SOCKOPT_PROTO_TLS_EXEC(sock, set_cret_list, optval, optlen);
640 break;
641
642 case TLS_CIPHERSUITE_LIST:
643 SAL_SOCKOPT_PROTO_TLS_EXEC(sock, set_ciphersurite, optval, optlen);
644 break;
645
646 case TLS_PEER_VERIFY:
647 SAL_SOCKOPT_PROTO_TLS_EXEC(sock, set_peer_verify, optval, optlen);
648 break;
649
650 case TLS_DTLS_ROLE:
651 SAL_SOCKOPT_PROTO_TLS_EXEC(sock, set_dtls_role, optval, optlen);
652 break;
653
654 default:
655 return -1;
656 }
657
658 return 0;
659 }
660 else
661 {
662 return sock->ops->setsockopt((int) sock->user_data, level, optname, optval, optlen);
663 }
664 #else
665 return sock->ops->setsockopt((int) sock->user_data, level, optname, optval, optlen);
666 #endif /* SAL_USING_TLS */
667 }
668
sal_connect(int socket,const struct sockaddr * name,socklen_t namelen)669 int sal_connect(int socket, const struct sockaddr *name, socklen_t namelen)
670 {
671 struct sal_socket *sock;
672 int ret;
673
674 sock = sal_get_socket(socket);
675 if (!sock)
676 {
677 return -1;
678 }
679
680 if (sock->ops->connect == RT_NULL)
681 {
682 return -RT_ENOSYS;
683 }
684
685 ret = sock->ops->connect((int) sock->user_data, name, namelen);
686 #ifdef SAL_USING_TLS
687 if (ret >= 0 && SAL_SOCKOPS_PROTO_TLS_VALID(sock, connect))
688 {
689 if (proto_tls->ops->connect(sock->user_data_tls) < 0)
690 {
691 return -1;
692 }
693
694 return ret;
695 }
696 #endif
697
698 return ret;
699 }
700
sal_listen(int socket,int backlog)701 int sal_listen(int socket, int backlog)
702 {
703 struct sal_socket *sock;
704
705 sock = sal_get_socket(socket);
706 if (!sock)
707 {
708 return -1;
709 }
710
711 if (sock->ops->listen == RT_NULL)
712 {
713 return -RT_ENOSYS;
714 }
715
716 return sock->ops->listen((int) sock->user_data, backlog);
717 }
718
sal_recvfrom(int socket,void * mem,size_t len,int flags,struct sockaddr * from,socklen_t * fromlen)719 int sal_recvfrom(int socket, void *mem, size_t len, int flags,
720 struct sockaddr *from, socklen_t *fromlen)
721 {
722 struct sal_socket *sock;
723
724 sock = sal_get_socket(socket);
725 if (!sock)
726 {
727 return -1;
728 }
729
730 if (sock->ops->recvfrom == RT_NULL)
731 {
732 return -RT_ENOSYS;
733 }
734
735 #ifdef SAL_USING_TLS
736 if (SAL_SOCKOPS_PROTO_TLS_VALID(sock, recv))
737 {
738 int ret;
739
740 if ((ret = proto_tls->ops->recv(sock->user_data_tls, mem, len)) < 0)
741 {
742 return -1;
743 }
744 return ret;
745 }
746 else
747 {
748 return sock->ops->recvfrom((int) sock->user_data, mem, len, flags, from, fromlen);
749 }
750 #else
751 return sock->ops->recvfrom((int) sock->user_data, mem, len, flags, from, fromlen);
752 #endif
753 }
754
sal_sendto(int socket,const void * dataptr,size_t size,int flags,const struct sockaddr * to,socklen_t tolen)755 int sal_sendto(int socket, const void *dataptr, size_t size, int flags,
756 const struct sockaddr *to, socklen_t tolen)
757 {
758 struct sal_socket *sock;
759
760 sock = sal_get_socket(socket);
761 if (!sock)
762 {
763 return -1;
764 }
765
766 if (sock->ops->sendto == RT_NULL)
767 {
768 return -RT_ENOSYS;
769 }
770
771 #ifdef SAL_USING_TLS
772 if (SAL_SOCKOPS_PROTO_TLS_VALID(sock, send))
773 {
774 int ret;
775
776 if ((ret = proto_tls->ops->send(sock->user_data_tls, dataptr, size)) < 0)
777 {
778 return -1;
779 }
780 return ret;
781 }
782 else
783 {
784 return sock->ops->sendto((int) sock->user_data, dataptr, size, flags, to, tolen);
785 }
786 #else
787 return sock->ops->sendto((int) sock->user_data, dataptr, size, flags, to, tolen);
788 #endif
789 }
790
sal_socket(int domain,int type,int protocol)791 int sal_socket(int domain, int type, int protocol)
792 {
793 int retval;
794 int socket, proto_socket;
795 struct sal_socket *sock;
796
797 /* allocate a new socket and registered socket options */
798 socket = socket_new();
799 if (socket < 0)
800 {
801 return -1;
802 }
803 sock = sal_get_socket(socket);
804
805 retval = socket_init(domain, type, protocol, &sock);
806 if (retval < 0)
807 {
808 LOG_E("SAL socket protocol family input failed, return error %d.", retval);
809 return -1;
810 }
811
812 if (sock->ops->socket == RT_NULL)
813 {
814 return -RT_ENOSYS;
815 }
816
817 proto_socket = sock->ops->socket(domain, type, protocol);
818 if (proto_socket >= 0)
819 {
820 #ifdef SAL_USING_TLS
821 if (SAL_SOCKOPS_PROTO_TLS_VALID(sock, socket))
822 {
823 sock->user_data_tls = proto_tls->ops->socket(proto_socket);
824 if (sock->user_data_tls == RT_NULL)
825 {
826 return -1;
827 }
828 }
829 #endif
830 sock->user_data = (void *) proto_socket;
831 return sock->socket;
832 }
833
834 return -1;
835 }
836
sal_closesocket(int socket)837 int sal_closesocket(int socket)
838 {
839 struct sal_socket *sock;
840
841 sock = sal_get_socket(socket);
842 if (!sock)
843 {
844 return -1;
845 }
846
847 if (sock->ops->closesocket == RT_NULL)
848 {
849 return -RT_ENOSYS;
850 }
851
852 if (sock->ops->closesocket((int) sock->user_data) == 0)
853 {
854 #ifdef SAL_USING_TLS
855 if (SAL_SOCKOPS_PROTO_TLS_VALID(sock, closesocket))
856 {
857 if (proto_tls->ops->closesocket(sock->user_data_tls) < 0)
858 {
859 return -1;
860 }
861 }
862 #endif
863 rt_free(sock);
864 socket_table.sockets[socket] = RT_NULL;
865 return 0;
866 }
867
868 return -1;
869 }
870
sal_ioctlsocket(int socket,long cmd,void * arg)871 int sal_ioctlsocket(int socket, long cmd, void *arg)
872 {
873 struct sal_socket *sock;
874
875 sock = sal_get_socket(socket);
876 if (!sock)
877 {
878 return -1;
879 }
880
881 if (sock->ops->ioctlsocket == RT_NULL)
882 {
883 return -RT_ENOSYS;
884 }
885
886 return sock->ops->ioctlsocket((int) sock->user_data, cmd, arg);
887 }
888
889 #ifdef SAL_USING_POSIX
sal_poll(struct dfs_fd * file,struct rt_pollreq * req)890 int sal_poll(struct dfs_fd *file, struct rt_pollreq *req)
891 {
892 struct sal_socket *sock;
893 int socket = (int) file->data;
894
895 sock = sal_get_socket(socket);
896 if (!sock)
897 {
898 return -1;
899 }
900
901 if (sock->ops->poll == RT_NULL)
902 {
903 return -RT_ENOSYS;
904 }
905
906 return sock->ops->poll(file, req);
907 }
908 #endif
909
sal_gethostbyname(const char * name)910 struct hostent *sal_gethostbyname(const char *name)
911 {
912 int i;
913 struct hostent *hst;
914
915 for (i = 0; i < SAL_PROTO_FAMILIES_NUM; ++i)
916 {
917 if (proto_families[i].ops && proto_families[i].ops->gethostbyname)
918 {
919 hst = proto_families[i].ops->gethostbyname(name);
920 if (hst != RT_NULL)
921 {
922 return hst;
923 }
924 }
925 }
926
927 return RT_NULL;
928 }
929
sal_gethostbyname_r(const char * name,struct hostent * ret,char * buf,size_t buflen,struct hostent ** result,int * h_errnop)930 int sal_gethostbyname_r(const char *name, struct hostent *ret, char *buf,
931 size_t buflen, struct hostent **result, int *h_errnop)
932 {
933 int i, res;
934
935 for (i = 0; i < SAL_PROTO_FAMILIES_NUM; ++i)
936 {
937 if (proto_families[i].ops && proto_families[i].ops->gethostbyname_r)
938 {
939 res = proto_families[i].ops->gethostbyname_r(name, ret, buf, buflen, result, h_errnop);
940 if (res == 0)
941 {
942 return res;
943 }
944 }
945 }
946
947 return -1;
948 }
949
sal_getaddrinfo(const char * nodename,const char * servname,const struct addrinfo * hints,struct addrinfo ** res)950 int sal_getaddrinfo(const char *nodename,
951 const char *servname,
952 const struct addrinfo *hints,
953 struct addrinfo **res)
954 {
955 int i, ret;
956
957 for (i = 0; i < SAL_PROTO_FAMILIES_NUM; ++i)
958 {
959 if (proto_families[i].ops && proto_families[i].ops->getaddrinfo)
960 {
961 ret = proto_families[i].ops->getaddrinfo(nodename, servname, hints, res);
962 if (ret == 0)
963 {
964 return ret;
965 }
966 }
967 }
968
969 return -1;
970 }
971
sal_freeaddrinfo(struct addrinfo * ai)972 void sal_freeaddrinfo(struct addrinfo *ai)
973 {
974 int i;
975
976 for (i = 0; i < SAL_PROTO_FAMILIES_NUM; ++i)
977 {
978 if (proto_families[i].ops && proto_families[i].ops->freeaddrinfo)
979 {
980 proto_families[i].ops->freeaddrinfo(ai);
981 return;
982 }
983 }
984 }
985