Barracuda Application Server C/C++ Reference
Native APIs, integration guides, and platform interfaces
gBsdSock.h
1/*
2 * ____ _________ __ _
3 * / __ \___ ____ _/ /_ __(_)___ ___ ___ / / ____ ____ _(_)____
4 * / /_/ / _ \/ __ `/ / / / / / __ `__ \/ _ \/ / / __ \/ __ `/ / ___/
5 * / _, _/ __/ /_/ / / / / / / / / / / / __/ /___/ /_/ / /_/ / / /__
6 * /_/ |_|\___/\__,_/_/ /_/ /_/_/ /_/ /_/\___/_____/\____/\__, /_/\___/
7 * /____/
8 *
9 * Barracuda Embedded Web-Server
10 *
11 ****************************************************************************
12 * HEADER
13 *
14 * $Id: gBsdSock.h 6657 2026-10-28 18:19:39Z wini $
15 *
16 * COPYRIGHT: Real Time Logic, 2004 - 2026
17 *
18 * This software is copyrighted by and is the sole property of Real
19 * Time Logic LLC. All rights, title, ownership, or other interests in
20 * the software remain the property of Real Time Logic LLC. This
21 * software may only be used in accordance with the terms and
22 * conditions stipulated in the corresponding license agreement under
23 * which the software has been supplied. Any unauthorized use,
24 * duplication, transmission, distribution, or disclosure of this
25 * software is expressly forbidden.
26 *
27 * This Copyright notice may not be removed or modified without prior
28 * written consent of Real Time Logic LLC.
29 *
30 * Real Time Logic LLC. reserves the right to modify this software
31 * without notice.
32 *
33 * http://realtimelogic.com
34 ****************************************************************************
35 *
36 *
37 * Do not directly include this file!!!
38 * gBsdSock -> Generic BSD socket functions.
39 */
40#ifndef _gBsdSock_h
41#define _gBsdSock_h
42#include <BaSocketConfig.h>
43
44#ifdef __cplusplus
45extern "C" {
46#endif
47
48struct HttpSockaddr;
49
50#ifndef basocklen_t
51#define basocklen_t socklen_t
52#endif
53
54#ifndef SocketHandle
55#define SocketHandle int
56#endif
57
58#ifndef socketAccept
59#define socketAccept accept
60#endif
61
62#ifndef socketBind
63#define socketBind bind
64#endif
65
66#ifndef socketClose
67#define socketClose close
68#endif
69
70#ifndef socketShutdown
71#define socketShutdown shutdown
72#endif
73
74#ifndef socketErrno
75#define socketErrno(s) errno
76#endif
77
78/* for setting blocking/non-blocking sockets */
79#ifndef socketIoctl
80#define socketIoctl ioctl
81#endif
82
83#ifndef socketGetPeerName
84#define socketGetPeerName getpeername
85#endif
86
87#ifndef socketGetSockName
88#define socketGetSockName getsockname
89#endif
90
91#ifndef socketListen
92#define socketListen listen
93#endif
94
95#ifndef socketRecv
96#define socketRecv recv
97#endif
98
99#ifndef socketSelect
100#define socketSelect select
101#endif
102
103#ifndef socketSend
104#define socketSend send
105#endif
106
107#ifndef socketSendto
108#define socketSendto sendto
109#endif
110
111#ifndef socketRecvfrom
112#define socketRecvfrom recvfrom
113#endif
114
115#ifndef socketGetsockopt
116#define socketGetsockopt getsockopt
117#endif
118
119#ifndef socketSetsockopt
120#define socketSetsockopt setsockopt
121#endif
122
123#ifndef socketSocket
124#define socketSocket socket
125#endif
126
127#ifndef socketInetAddr
128#define socketInetAddr inet_addr
129#endif
130
131#ifndef socketInetPton
132#define socketInetPton inet_pton
133#endif
134
135#ifndef socketGethostbyname
136#define socketGethostbyname gethostbyname
137#endif
138
139#ifndef socketInetNtoa
140#define socketInetNtoa inet_ntoa
141#endif
142
143#ifndef socketWouldBlock
144#define socketWouldBlock(s) (EWOULDBLOCK == socketErrno(s))
145#endif
146
147#ifndef socketInProgress
148#ifdef EINPROGRESS
149#define socketInProgress(s) (EINPROGRESS == socketErrno(s))
150#else
151#define socketInProgress(s) 0
152#endif
153#endif
154
155#ifndef socketConnect
156#define socketConnect connect
157#endif
158
159#ifndef BaSockAddrStorage
160#define BaSockAddrStorage struct sockaddr_storage
161#endif
162
163
164
165/* FD_CLOEXEC if applicable for platform */
166#ifndef HttpSocket_setcloexec
167#define HttpSocket_setcloexec(x)
168#endif
169#ifndef HttpSocket_clearcloexec
170#define HttpSocket_clearcloexec(x)
171#endif
172#ifndef basocketpair
173#define basocketpair(x)
174#endif
175
176typedef struct {
177 SocketHandle hndl;
178} HttpSocket;
179
180
181#ifndef HttpSocket_accept
182#define HttpSocket_accept(o, conSock, status) do { \
183 (conSock)->hndl=socketAccept((o)->hndl, NULL, NULL); \
184 *(status) = (HttpSocket_isValid(conSock)) ? 0 : -1; \
185 HttpSocket_setcloexec(o); \
186}while(0)
187#endif
188
189
190#ifndef HttpSocket_bind
191#define HttpSocket_bindIp4(o, sockAddr, port, status) do { \
192 struct sockaddr_in in; \
193 memset(&in, 0, sizeof(struct sockaddr_in)); \
194 in.sin_family = AF_INET; \
195 in.sin_port = baHtons(port); \
196 memcpy(&in.sin_addr.s_addr,(sockAddr)->addr, 4); \
197 *(status) = socketBind((o)->hndl, (struct sockaddr *)&in, \
198 sizeof(struct sockaddr_in)); \
199} while(0)
200#if BA_ENABLE_IPV6
201#define HttpSocket_bindIp6(o, sockAddr, port, status) do { \
202 struct sockaddr_in6 in6; \
203 memset(&in6, 0, sizeof(struct sockaddr_in6)); \
204 in6.sin6_family = AF_INET6; \
205 in6.sin6_port = baHtons(port); \
206 memcpy(&in6.sin6_addr, (sockAddr)->addr, 16); \
207 *(status) = socketBind((o)->hndl, (struct sockaddr*)&in6, \
208 sizeof(struct sockaddr_in6)); \
209} while(0)
210#else
211#define HttpSocket_bindIp6(o, sockAddr, port, status) *status=-1
212#endif
213#define HttpSocket_bind(o, sockAddr, port, status) do { \
214 if((sockAddr)->isIp6) \
215 HttpSocket_bindIp6(o, sockAddr, port, status); \
216 else \
217 HttpSocket_bindIp4(o, sockAddr, port, status); \
218}while(0)
219#endif
220
221#ifndef HttpSocket_close
222#define HttpSocket_close(o) do {\
223 int status;\
224 HttpSocket_setNonblocking(o,&status);\
225 (void)status; \
226 socketClose((o)->hndl);\
227 HttpSocket_invalidate(o);\
228 } while(0)
229#endif
230
231
232/* Perform a hard (abortive) close */
233#ifndef HttpSocket_hardClose
234#define HttpSocket_hardClose(o) do {\
235 struct linger l;\
236 l.l_onoff = 1; l.l_linger = 0;\
237 socketSetsockopt((o)->hndl,SOL_SOCKET,SO_LINGER, \
238 (char*)&l,sizeof(struct linger)); \
239 socketClose((o)->hndl);\
240 HttpSocket_invalidate(o);\
241 } while(0)
242#endif
243
244
245/* SHUT_RDWR or 2 Further sends and receives are disallowed */
246#ifndef HttpSocket_shutdown
247#define HttpSocket_shutdown(o) do {\
248 int status;\
249 HttpSocket_setBlocking(o,&status);\
250 (void)status; \
251 socketShutdown((o)->hndl,2);\
252 socketClose((o)->hndl);\
253 HttpSocket_invalidate(o);\
254 } while(0)
255#endif
256
257
258#ifndef HttpSocket_constructor
259#define HttpSocket_constructor(o) do { \
260 memset(o, 0, sizeof(HttpSocket)); \
261 HttpSocket_invalidate(o); \
262}while(0)
263#endif
264
265#ifndef HttpSocket_errno
266#define HttpSocket_errno(o, status, ecode) (void)status,*(ecode) = socketErrno((o)->hndl)
267#endif
268
269#ifndef HttpSocket_getId
270#define HttpSocket_getId(o) (int)(o)->hndl
271#endif
272
273#ifndef HttpSocket_getPeerName
274#if BA_ENABLE_IPV6
275#define HttpSocket_getPeerName(o, addrMA, port, isIp6MA, status) do {\
276 BaSockAddrStorage a;\
277 basocklen_t aLen = sizeof(a);\
278 if( !(*(status) = socketGetPeerName((o)->hndl, (struct sockaddr *)&a, &aLen)) )\
279 {\
280 if(isIp6MA){\
281 memcpy(&(addrMA)->addr, &((struct sockaddr_in6*)&a)->sin6_addr, 16);\
282 if(port) *(port)=baHtons(((struct sockaddr_in6*)&a)->sin6_port);\
283 }\
284 else {\
285 *((U32*)(addrMA)->addr) = ((struct sockaddr_in*)&a)->sin_addr.s_addr;\
286 if(port) *(port)=baHtons(((struct sockaddr_in*)&a)->sin_port);\
287 }\
288 (addrMA)->isIp6=isIp6MA; \
289 }\
290} while(0)
291#else
292#define HttpSocket_getPeerName(o, sockAddr, port, isIp6MA, status) do { \
293 struct sockaddr_in in; basocklen_t size=sizeof(struct sockaddr_in);\
294 (void)isIp6MA; \
295 *(status) = socketGetPeerName((o)->hndl, (struct sockaddr *)&in, &size); \
296 memcpy((sockAddr)->addr, &in.sin_addr.s_addr, 4);\
297 if(port) *(port)=baHtons(in.sin_port);\
298 (sockAddr)->isIp6=FALSE; \
299} while(0)
300#endif
301#endif
302
303#ifndef HttpSocket_getSockName
304#if BA_ENABLE_IPV6
305#define HttpSocket_getSockName(o, addrMA, port, isIp6MA, status) do {\
306 BaSockAddrStorage a;\
307 basocklen_t aLen = sizeof(a);\
308 if( !(*(status) = socketGetSockName((o)->hndl,(struct sockaddr*)&a,&aLen)) )\
309 {\
310 if(isIp6MA){\
311 memcpy(&(addrMA)->addr, &((struct sockaddr_in6*)&a)->sin6_addr, 16);\
312 if(port) *(port)=baHtons(((struct sockaddr_in6*)&a)->sin6_port);\
313 }\
314 else {\
315 *((U32*)(addrMA)->addr) = ((struct sockaddr_in*)&a)->sin_addr.s_addr;\
316 if(port) *(port)=baHtons(((struct sockaddr_in*)&a)->sin_port);\
317 }\
318 (addrMA)->isIp6=isIp6MA; \
319 }\
320} while(0)
321#else
322#define HttpSocket_getSockName(o, sockAddr, port, isIp6MA, status) do { \
323 struct sockaddr_in in; basocklen_t size=sizeof(struct sockaddr_in);\
324 (void)isIp6MA; \
325 *(status) = socketGetSockName((o)->hndl, (struct sockaddr *)&in, &size); \
326 memcpy((sockAddr)->addr, &in.sin_addr.s_addr, 4);\
327 if(port) *(port)=baHtons(in.sin_port);\
328 (sockAddr)->isIp6=FALSE; \
329} while(0)
330#endif
331#endif
332
333#ifndef HttpSocket_invalidate
334#define HttpSocket_invalidate(o) (o)->hndl = -1
335#endif
336
337#ifndef HttpSocket_isValid
338#define HttpSocket_isValid(o) ((o)->hndl >= 0)
339#endif
340
341#ifndef HttpSocket_listen
342#define HttpSocket_listen(o, sockaddrNotUsed, queueSize, status) do { \
343 *(status)=socketListen((o)->hndl, queueSize); \
344 HttpSocket_setcloexec(o); \
345}while(0)
346#endif
347
348#ifndef HttpSocket_move
349#define HttpSocket_move(o, newS) do{ \
350 (newS)->hndl=(o)->hndl;HttpSocket_invalidate(o);}while(0)
351#endif
352
353#ifndef HttpSocket_recv
354#define HttpSocket_recv(o, data, len, retLen) do { \
355 *(retLen)=(int)socketRecv((o)->hndl,data,len,0); \
356 if(*(retLen) <= 0) { \
357 if(*(retLen) < 0) { \
358 int wb; \
359 HttpSocket_wouldBlock(o, &wb); \
360 if(wb) \
361 *(retLen)=0; /* No data */ \
362 } \
363 else *(retLen) = -1; /* graceful disconnect */ \
364 } \
365} while(0)
366#endif
367
368#ifndef HttpSocket_send
369#define HttpSocket_send(o, m, isTerminated, data, len, retLen) do { \
370 if(m && ThreadMutex_isOwner(m)) { \
371 ThreadMutex_release(m); \
372 *(retLen)=(int)socketSend((o)->hndl,data,len,0); \
373 ThreadMutex_set(m); \
374 } \
375 else { \
376 *(retLen)=(int)socketSend((o)->hndl,data,len,0); \
377 } \
378 if(*(retLen) < 0) { \
379 int wb; \
380 HttpSocket_wouldBlock(o, &wb); \
381 if(wb) \
382 *(retLen)=0; /* non blocking, no data sent */ \
383 } \
384} while(0)
385#endif
386
387#if BA_USE_GETADDRINFO
388#ifndef HttpSocket_sendto
389#define HttpSocket_sendto(o, data, len, addr, addrlen, retLen) do { \
390 *(retLen)=(int)socketSendto((o)->hndl,data,len,0, addr, addrlen); \
391} while(0)
392#endif
393#else
394#ifndef HttpSocket_sendto
395#define HttpSocket_sendtoV4(o, data, len, addrMA, port, status) \
396 struct sockaddr_in sin; \
397 memset((char *)&sin, 0, sizeof(sin)); \
398 sin.sin_family = AF_INET; \
399 sin.sin_port = baHtons(port); \
400 memcpy(&sin.sin_addr.s_addr, (addrMA)->addr, 4); \
401 *(status) = (int)socketSendto((o)->hndl,data,len,0, \
402 (struct sockaddr *)&sin, sizeof(sin));
403#if BA_ENABLE_IPV6
404#define HttpSocket_sendtoV6(o, data, len, addrMA, port, status) \
405 struct sockaddr_in6 sin6; \
406 memset((char *)&sin6, 0, sizeof(sin6)); \
407 sin6.sin6_family = (addrMA)->isIp6 ? AF_INET6 : AF_INET; \
408 sin6.sin6_port = baHtons(port); \
409 memcpy(&sin6.sin6_addr, (addrMA)->addr, 16); \
410 *(status)=(int)socketSendto((o)->hndl,data,len,0, \
411 (struct sockaddr *)&sin6,sizeof(sin6));
412#define HttpSocket_sendto(o, data, len, addrMA, port, status) do {\
413 if((addrMA)->isIp6) {\
414 HttpSocket_sendtoV6(o, data, len, addrMA, port, status)\
415 }\
416 else {\
417 HttpSocket_sendtoV4(o, data, len, addrMA, port, status)\
418 }\
419} while(0)
420#else
421#define HttpSocket_sendto(o, data, len, addrMA, port, status) do { \
422 HttpSocket_sendtoV4(o, data, len, addrMA, port, status) } while(0)
423#endif
424#endif
425#endif
426
427#ifndef baIoctlArg
428#define baIoctlArg size_t
429#endif
430
431#ifndef HttpSocket_setBlocking
432#define HttpSocket_setBlocking(o, status) do { \
433 baIoctlArg arg=0; /*Set blocking mode */ \
434 *(status)=socketIoctl((o)->hndl, FIONBIO, &arg); \
435} while(0)
436#endif
437
438#ifndef HttpSocket_setNonblocking
439#define HttpSocket_setNonblocking(o, status) \
440do { \
441 baIoctlArg arg=1; /* Set non-blocking mode */ \
442 *(status)=socketIoctl((o)->hndl, FIONBIO, &arg); \
443} while(0)
444#endif
445
446#ifndef HttpSocket_setTCPNoDelay
447#define HttpSocket_setTCPNoDelay(o, enable, status) do { \
448 int enableFlag = enable ? 1 : 0; \
449 *(status) = socketSetsockopt((o)->hndl, IPPROTO_TCP, TCP_NODELAY, \
450 (char*)&enableFlag, sizeof(int)); \
451}while(0)
452#endif
453
454#if !defined(HttpSocket_getKeepAlive) && defined(SO_KEEPALIVE)
455#define HttpSocket_getKeepAlive(o,enablePtr,statusPtr) do { \
456 int optval; \
457 socklen_t optlen = sizeof(optval); \
458 *(statusPtr) = \
459 socketGetsockopt((o)->hndl,SOL_SOCKET,SO_KEEPALIVE, \
460 (char*)&optval,&optlen)<0 ? \
461 -1 : 0; \
462 *(enablePtr) = optval; \
463 } while(0)
464#endif
465
466#if !defined(HttpSocket_setKeepAlive) && defined(SO_KEEPALIVE)
467#define HttpSocket_setKeepAlive(o,enable,statusPtr) do { \
468 int optval=enable; \
469 basocklen_t optlen = sizeof(optval); \
470 *(statusPtr) = \
471 socketSetsockopt((o)->hndl,SOL_SOCKET,SO_KEEPALIVE, \
472 (char*)&optval,optlen)<0 ? \
473 -1 : 0; \
474} while(0)
475#endif
476
477
478#ifndef HttpSocket_soReuseaddr
479#ifndef BA_ENABLE_SOCKET_REUSE_ADDRESS
480#define BA_ENABLE_SOCKET_REUSE_ADDRESS 1
481#endif
482#if BA_ENABLE_SOCKET_REUSE_ADDRESS
483#define HttpSocket_soReuseaddr(o, status) do { \
484 int enableFlag = 1; \
485 *(status) = socketSetsockopt((o)->hndl, SOL_SOCKET, SO_REUSEADDR, \
486 (char*)&enableFlag, sizeof(int)); \
487}while(0)
488#else
489#define HttpSocket_soReuseaddr(o, status)
490#endif
491#endif
492
493#ifndef HttpSocket_soDontroute
494#define HttpSocket_soDontroute(o, enableFlag, status) do { \
495 *(status) = socketSetsockopt((o)->hndl, SOL_SOCKET, SO_DONTROUTE, \
496 (char*)&enableFlag, sizeof(int)); \
497}while(0)
498#endif
499
500#ifndef HttpSocket_soBroadcast
501#define HttpSocket_soBroadcast(o, enableFlag, status) do { \
502 *(status) = socketSetsockopt((o)->hndl, SOL_SOCKET, SO_BROADCAST, \
503 (char*)&enableFlag, sizeof(int)); \
504}while(0)
505#endif
506
507
508#ifndef HttpSocket_sockStream
509#if BA_ENABLE_IPV6
510#define HttpSocket_sockStreamIp6(o, status) do { \
511 (o)->hndl=socketSocket(AF_INET6, SOCK_STREAM, 0); \
512 *(status) = HttpSocket_isValid(o) ? 0 : -1; \
513}while(0)
514#else
515#define HttpSocket_sockStreamIp6(o, status) HttpSocket_sockStreamIp4(o, status)
516#endif
517
518#define HttpSocket_sockStreamIp4(o, status) do { \
519 (o)->hndl=socketSocket(AF_INET, SOCK_STREAM, 0); \
520 *(status) = HttpSocket_isValid(o) ? 0 : -1; \
521}while(0)
522
523#define HttpSocket_sockStream(o, interfNameNotUsed, useIp6, status) do { \
524 if(useIp6) \
525 HttpSocket_sockStreamIp6(o, status); \
526 else \
527 HttpSocket_sockStreamIp4(o, status); \
528}while(0)
529#endif
530
531#if BA_ENABLE_UDP
532
533#ifndef ba_nametoindex
534#define ba_nametoindex(name, resp,status) *(resp)=if_nametoindex(name)
535#endif
536
537
538#ifndef HttpSocket_sockUdp
539#if BA_ENABLE_IPV6
540#define HttpSocket_sockUdpIp6(o, status) do { \
541 (o)->hndl=socketSocket(AF_INET6, SOCK_DGRAM, 0); \
542 *(status) = HttpSocket_isValid(o) ? 0 : -1; \
543}while(0)
544#else
545#define HttpSocket_sockUdpIp6(o, status) HttpSocket_sockUdpIp4(o, status)
546#endif
547
548#define HttpSocket_sockUdpIp4(o, status) do { \
549 (o)->hndl=socketSocket(AF_INET, SOCK_DGRAM, 0); \
550 *(status) = HttpSocket_isValid(o) ? 0 : -1; \
551}while(0)
552
553#define HttpSocket_sockUdp(o, interfNameNotUsed, useIp6, status) do { \
554 if(useIp6) \
555 HttpSocket_sockUdpIp6(o, status); \
556 else \
557 HttpSocket_sockUdpIp4(o, status); \
558}while(0)
559#endif
560
561#ifndef HttpSocket_recvfrom
562#define HttpSocket_recvfromIp4(o,data,len,sockAddr,port,status) do { \
563 struct sockaddr_in in; basocklen_t size=sizeof(struct sockaddr_in);\
564 *(status)=socketRecvfrom((o)->hndl,data,len,0,(struct sockaddr*)&in,&size); \
565 memcpy((sockAddr)->addr, &in.sin_addr.s_addr, 4);\
566 *(port)=baHtons(in.sin_port);\
567} while(0)
568#if BA_ENABLE_IPV6
569#define HttpSocket_recvfromIp6(o,data,len,sockAddr,port,status) do { \
570 struct sockaddr_in6 in6; basocklen_t size=sizeof(struct sockaddr_in6);\
571 *(status)=socketRecvfrom((o)->hndl,data,len,0,(struct sockaddr*)&in6,&size);\
572 memcpy(sockAddr, &in6.sin6_addr, 16); \
573 *(port)=baHtons(in6.sin6_port);\
574} while(0)
575#else
576#define HttpSocket_recvfromIp6(o,data,len,sockAddr,port,status) *status=-1
577#endif
578#define HttpSocket_recvfrom(o,data,len,sockAddr,port,status) do { \
579 if((sockAddr)->isIp6) \
580 HttpSocket_recvfromIp6(o,data,len,sockAddr,port,status); \
581 else \
582 HttpSocket_recvfromIp4(o,data,len,sockAddr,port,status); \
583}while(0)
584#endif
585
586
587#ifndef HttpSocket_setmembership
588BA_API int HttpSocket_setmembership(HttpSocket* o,
589 BaBool enable,
590 BaBool ipv6,
591 const char* multiAddrName,
592 const char* intfName);
593#endif
594
595#endif /* BA_ENABLE_UDP */
596
597#ifndef HttpSocket_wouldBlock
598#define HttpSocket_wouldBlock(o, status) do { \
599 *(status)=socketWouldBlock((o)->hndl); \
600 if(!*(status)) { \
601 *(status)=socketInProgress((o)->hndl); \
602 } \
603} while(0)
604#endif
605
606
607/*
608HttpSocket_connect(HttpSocket*, HttpSockaddr*, U16 port, int* status)
609*/
610#ifndef HttpSocket_connect
611#define HttpSocket_connectV4(o, addrMA, port, status) \
612 struct sockaddr_in sin; \
613 memset((char *)&sin, 0, sizeof(sin)); \
614 sin.sin_family = AF_INET; \
615 sin.sin_port = baHtons(port); \
616 memcpy(&sin.sin_addr.s_addr, (addrMA)->addr, 4);\
617 *(status) = socketConnect((o)->hndl,(struct sockaddr *)&sin, sizeof(sin));
618#if BA_ENABLE_IPV6
619#define HttpSocket_connectV6(o, addrMA, port, status)\
620 struct sockaddr_in6 sin6; \
621 memset((char *)&sin6, 0, sizeof(sin6)); \
622 sin6.sin6_family = (addrMA)->isIp6 ? AF_INET6 : AF_INET; \
623 sin6.sin6_port = baHtons(port); \
624 memcpy(&sin6.sin6_addr, (addrMA)->addr, 16); \
625 *(status)=socketConnect((o)->hndl,(struct sockaddr *)&sin6,sizeof(sin6));
626#define HttpSocket_connect(o, addrMA, port, status) do {\
627 if((addrMA)->isIp6) {\
628 HttpSocket_connectV6(o, addrMA, port, status)\
629 }\
630 else {\
631 HttpSocket_connectV4(o, addrMA, port, status)\
632 }\
633} while(0)
634#else
635#define HttpSocket_connect(o, addr, port, status) do {\
636 HttpSocket_connectV4(o, addr, port, status) } while(0)
637#endif
638#endif
639
640
641
642/*
643 Returns:
644 < 0: Sock error code
645 0: OK
646*/
647BA_API int HttpSocket_create(HttpSocket* o,
648 const char* bindIntfName,
649 U16 port,
650 BaBool dgram,
651 BaBool ipv6);
652
653typedef struct HttpSockaddr {
654 char addr[16];
655 BaBool isIp6;
656} HttpSockaddr;
657
658
659#ifndef HttpSockaddr_gethostbynameIp6
660#if BA_ENABLE_IPV6
661#define HttpSockaddr_gethostbynameIp6(o, host, status) do { \
662 if(host) { \
663 struct addrinfo hints, *servinfo; \
664 memset(&hints, 0, sizeof hints); \
665 hints.ai_family = AF_INET6; \
666 hints.ai_socktype = SOCK_STREAM; \
667 *(status) = getaddrinfo(host, 0, &hints, &servinfo); \
668 if( ! *(status) ) { \
669 memcpy((o)->addr, \
670 &((struct sockaddr_in6*)servinfo->ai_addr)->sin6_addr, 16); \
671 freeaddrinfo(servinfo); \
672 } \
673 } \
674 else { \
675 memset((o)->addr, 0, 16); \
676 *(status)=0; \
677 } \
678 (o)->isIp6=TRUE; \
679}while(0)
680#else
681#define HttpSockaddr_gethostbynameIp6(o, host, status) \
682 HttpSockaddr_gethostbynameIp4(o, host, status)
683#endif
684#endif
685
686#ifndef HttpSockaddr_gethostbyname
687#if BA_USE_GETADDRINFO
688#define HttpSockaddr_gethostbynameIp4(o, host, status) do { \
689 (o)->isIp6=FALSE; \
690 *(status)=0; \
691 if(host) { \
692 struct addrinfo hints, *result; \
693 memset(&hints, 0, sizeof(hints)); \
694 hints.ai_family=AF_INET; \
695 *(status)=getaddrinfo(host, 0, &hints, &result); \
696 if(!*(status)) { \
697 memcpy((o)->addr, &((struct sockaddr_in*)result->ai_addr)->sin_addr, 4); \
698 freeaddrinfo(result); \
699 } \
700 } \
701 else memset((o)->addr, 0, 4); \
702} while(0)
703#else
704#define HttpSockaddr_gethostbynameIp4(o, host, status) do { \
705 unsigned long ipAddr; \
706 (o)->isIp6=FALSE; \
707 *(status)=0; \
708 if(host) \
709 { \
710 ipAddr = socketInetAddr(host); /* is "host" an IP address ? */ \
711 if(ipAddr == INADDR_NONE) /* No, not an IP address. */ \
712 { /* Is "host" a hostname ? */\
713 struct hostent* hostInfo = socketGethostbyname((char*)host); \
714 if(!hostInfo) \
715 *(status)=-1; \
716 else \
717 memcpy(&ipAddr,&((struct in_addr *)hostInfo->h_addr)->s_addr,4);\
718 } \
719 } \
720 else \
721 ipAddr = baHtonl(INADDR_ANY); \
722 memcpy((o)->addr,&ipAddr, 4); \
723}while(0)
724
725
726#endif /* BA_USE_GETADDRINFO */
727
728#define HttpSockaddr_gethostbyname(o, host, useIp6, status) do { \
729 if(useIp6) \
730 HttpSockaddr_gethostbynameIp6(o, host, status); \
731 else \
732 HttpSockaddr_gethostbynameIp4(o, host, status); \
733}while(0)
734#endif
735
736
737#ifndef HttpSockaddr_addr2String
738BA_API void HttpSockaddr_addr2String(
739 HttpSockaddr* o, char* buf, int bufLen, int* status);
740#endif
741
742
743#ifndef HttpSockaddr_inetAddr
744BA_API void HttpSockaddr_inetAddr(
745 HttpSockaddr* o, const char* host, BaBool useIp6, int* status);
746#endif
747
748
749#ifdef __cplusplus
750}
751#endif
752
753
754#if BA_USE_GETADDRINFO
755
756#ifndef BaAddrinfo
757typedef struct addrinfo BaAddrinfo;
758#endif
759
760#ifndef BaAddrinfo_hintsInit
761#define BaAddrinfo_hintsInit(hints, dgram, ipv6) do { \
762 memset(hints, 0, sizeof(BaAddrinfo)); \
763 (hints)->ai_socktype = dgram ? SOCK_DGRAM : SOCK_STREAM; \
764 (hints)->ai_family = ipv6 ? PF_INET6 : PF_INET; \
765 } while(0)
766#endif
767
768#ifndef BaAddrinfo_get
769#define BaAddrinfo_get(node, service,hints,res,status,errinfo) do { \
770 *(status) = getaddrinfo(node, service, hints, res); \
771 *(errinfo) = *(status) ? (char*)gai_strerror(*(status)) : 0; \
772} while(0)
773#endif
774
775#ifndef BaAddrinfo_next
776#define BaAddrinfo_next(iter) *((iter)) = (*(iter))->ai_next
777#endif
778
779#ifndef BaAddrinfo_free
780#define BaAddrinfo_free(addr) freeaddrinfo(addr)
781#endif
782
783#ifndef BaAddrinfo_isIp6
784#define BaAddrinfo_isIp6(addr) (addr)->ai_family == AF_INET6
785#endif
786
787#ifndef BaAddrinfo_connect
788int BaAddrinfo_connect(BaAddrinfo* addr, HttpSocket* s, U32 timeout);
789#endif
790
791#ifndef BaAddrinfo_sendto
792#define BaAddrinfo_sendto(addr, s, data, len, status) \
793 HttpSocket_sendto(s, data, len, (addr)->ai_addr, \
794 (socklen_t)(addr)->ai_addrlen, status)
795#endif
796
797#endif /* BA_USE_GETADDRINFO */
798
799
800#endif
uint16_t U16
Unsigned 16-bit integer.
Definition: GenPrimT.h:94
uint32_t U32
Unsigned 32-bit integer.
Definition: GenPrimT.h:96
U8 BaBool
Boolean stored in an unsigned byte; FALSE is zero and TRUE is one.
Definition: GenPrimT.h:121