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