xref: /nrf52832-nimble/rt-thread/components/net/sal_socket/src/sal_socket.c (revision 104654410c56c573564690304ae786df310c91fc)
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