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