42#include <BaSocketConfig.h>
51#define basocklen_t socklen_t
55#define SocketHandle int
59#define socketAccept accept
63#define socketBind bind
67#define socketClose close
71#define socketShutdown shutdown
75#define socketErrno(s) errno
80#define socketIoctl ioctl
83#ifndef socketGetPeerName
84#define socketGetPeerName getpeername
87#ifndef socketGetSockName
88#define socketGetSockName getsockname
92#define socketListen listen
96#define socketRecv recv
100#define socketSelect select
104#define socketSend send
108#define socketSendto sendto
111#ifndef socketRecvfrom
112#define socketRecvfrom recvfrom
115#ifndef socketGetsockopt
116#define socketGetsockopt getsockopt
119#ifndef socketSetsockopt
120#define socketSetsockopt setsockopt
124#define socketSocket socket
127#ifndef socketInetAddr
128#define socketInetAddr inet_addr
131#ifndef socketInetPton
132#define socketInetPton inet_pton
135#ifndef socketGethostbyname
136#define socketGethostbyname gethostbyname
139#ifndef socketInetNtoa
140#define socketInetNtoa inet_ntoa
143#ifndef socketWouldBlock
144#define socketWouldBlock(s) (EWOULDBLOCK == socketErrno(s))
147#ifndef socketInProgress
149#define socketInProgress(s) (EINPROGRESS == socketErrno(s))
151#define socketInProgress(s) 0
156#define socketConnect connect
159#ifndef BaSockAddrStorage
160#define BaSockAddrStorage struct sockaddr_storage
166#ifndef HttpSocket_setcloexec
167#define HttpSocket_setcloexec(x)
169#ifndef HttpSocket_clearcloexec
170#define HttpSocket_clearcloexec(x)
173#define basocketpair(x)
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); \
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)); \
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)); \
211#define HttpSocket_bindIp6(o, sockAddr, port, status) *status=-1
213#define HttpSocket_bind(o, sockAddr, port, status) do { \
214 if((sockAddr)->isIp6) \
215 HttpSocket_bindIp6(o, sockAddr, port, status); \
217 HttpSocket_bindIp4(o, sockAddr, port, status); \
221#ifndef HttpSocket_close
222#define HttpSocket_close(o) do {\
224 HttpSocket_setNonblocking(o,&status);\
226 socketClose((o)->hndl);\
227 HttpSocket_invalidate(o);\
233#ifndef HttpSocket_hardClose
234#define HttpSocket_hardClose(o) do {\
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);\
246#ifndef HttpSocket_shutdown
247#define HttpSocket_shutdown(o) do {\
249 HttpSocket_setBlocking(o,&status);\
251 socketShutdown((o)->hndl,2);\
252 socketClose((o)->hndl);\
253 HttpSocket_invalidate(o);\
258#ifndef HttpSocket_constructor
259#define HttpSocket_constructor(o) do { \
260 memset(o, 0, sizeof(HttpSocket)); \
261 HttpSocket_invalidate(o); \
265#ifndef HttpSocket_errno
266#define HttpSocket_errno(o, status, ecode) (void)status,*(ecode) = socketErrno((o)->hndl)
269#ifndef HttpSocket_getId
270#define HttpSocket_getId(o) (int)(o)->hndl
273#ifndef HttpSocket_getPeerName
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)) )\
281 memcpy(&(addrMA)->addr, &((struct sockaddr_in6*)&a)->sin6_addr, 16);\
282 if(port) *(port)=baHtons(((struct sockaddr_in6*)&a)->sin6_port);\
285 *((U32*)(addrMA)->addr) = ((struct sockaddr_in*)&a)->sin_addr.s_addr;\
286 if(port) *(port)=baHtons(((struct sockaddr_in*)&a)->sin_port);\
288 (addrMA)->isIp6=isIp6MA; \
292#define HttpSocket_getPeerName(o, sockAddr, port, isIp6MA, status) do { \
293 struct sockaddr_in in; basocklen_t size=sizeof(struct sockaddr_in);\
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; \
303#ifndef HttpSocket_getSockName
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)) )\
311 memcpy(&(addrMA)->addr, &((struct sockaddr_in6*)&a)->sin6_addr, 16);\
312 if(port) *(port)=baHtons(((struct sockaddr_in6*)&a)->sin6_port);\
315 *((U32*)(addrMA)->addr) = ((struct sockaddr_in*)&a)->sin_addr.s_addr;\
316 if(port) *(port)=baHtons(((struct sockaddr_in*)&a)->sin_port);\
318 (addrMA)->isIp6=isIp6MA; \
322#define HttpSocket_getSockName(o, sockAddr, port, isIp6MA, status) do { \
323 struct sockaddr_in in; basocklen_t size=sizeof(struct sockaddr_in);\
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; \
333#ifndef HttpSocket_invalidate
334#define HttpSocket_invalidate(o) (o)->hndl = -1
337#ifndef HttpSocket_isValid
338#define HttpSocket_isValid(o) ((o)->hndl >= 0)
341#ifndef HttpSocket_listen
342#define HttpSocket_listen(o, sockaddrNotUsed, queueSize, status) do { \
343 *(status)=socketListen((o)->hndl, queueSize); \
344 HttpSocket_setcloexec(o); \
348#ifndef HttpSocket_move
349#define HttpSocket_move(o, newS) do{ \
350 (newS)->hndl=(o)->hndl;HttpSocket_invalidate(o);}while(0)
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) { \
359 HttpSocket_wouldBlock(o, &wb); \
363 else *(retLen) = -1; \
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); \
376 *(retLen)=(int)socketSend((o)->hndl,data,len,0); \
378 if(*(retLen) < 0) { \
380 HttpSocket_wouldBlock(o, &wb); \
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); \
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));
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)\
417 HttpSocket_sendtoV4(o, data, len, addrMA, port, status)\
421#define HttpSocket_sendto(o, data, len, addrMA, port, status) do { \
422 HttpSocket_sendtoV4(o, data, len, addrMA, port, status) } while(0)
428#define baIoctlArg size_t
431#ifndef HttpSocket_setBlocking
432#define HttpSocket_setBlocking(o, status) do { \
434 *(status)=socketIoctl((o)->hndl, FIONBIO, &arg); \
438#ifndef HttpSocket_setNonblocking
439#define HttpSocket_setNonblocking(o, status) \
442 *(status)=socketIoctl((o)->hndl, FIONBIO, &arg); \
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)); \
454#if !defined(HttpSocket_getKeepAlive) && defined(SO_KEEPALIVE)
455#define HttpSocket_getKeepAlive(o,enablePtr,statusPtr) do { \
457 socklen_t optlen = sizeof(optval); \
459 socketGetsockopt((o)->hndl,SOL_SOCKET,SO_KEEPALIVE, \
460 (char*)&optval,&optlen)<0 ? \
462 *(enablePtr) = optval; \
466#if !defined(HttpSocket_setKeepAlive) && defined(SO_KEEPALIVE)
467#define HttpSocket_setKeepAlive(o,enable,statusPtr) do { \
469 basocklen_t optlen = sizeof(optval); \
471 socketSetsockopt((o)->hndl,SOL_SOCKET,SO_KEEPALIVE, \
472 (char*)&optval,optlen)<0 ? \
478#ifndef HttpSocket_soReuseaddr
479#ifndef BA_ENABLE_SOCKET_REUSE_ADDRESS
480#define BA_ENABLE_SOCKET_REUSE_ADDRESS 1
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)); \
489#define HttpSocket_soReuseaddr(o, status)
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)); \
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)); \
508#ifndef HttpSocket_sockStream
510#define HttpSocket_sockStreamIp6(o, status) do { \
511 (o)->hndl=socketSocket(AF_INET6, SOCK_STREAM, 0); \
512 *(status) = HttpSocket_isValid(o) ? 0 : -1; \
515#define HttpSocket_sockStreamIp6(o, status) HttpSocket_sockStreamIp4(o, status)
518#define HttpSocket_sockStreamIp4(o, status) do { \
519 (o)->hndl=socketSocket(AF_INET, SOCK_STREAM, 0); \
520 *(status) = HttpSocket_isValid(o) ? 0 : -1; \
523#define HttpSocket_sockStream(o, interfNameNotUsed, useIp6, status) do { \
525 HttpSocket_sockStreamIp6(o, status); \
527 HttpSocket_sockStreamIp4(o, status); \
533#ifndef ba_nametoindex
534#define ba_nametoindex(name, resp,status) *(resp)=if_nametoindex(name)
538#ifndef HttpSocket_sockUdp
540#define HttpSocket_sockUdpIp6(o, status) do { \
541 (o)->hndl=socketSocket(AF_INET6, SOCK_DGRAM, 0); \
542 *(status) = HttpSocket_isValid(o) ? 0 : -1; \
545#define HttpSocket_sockUdpIp6(o, status) HttpSocket_sockUdpIp4(o, status)
548#define HttpSocket_sockUdpIp4(o, status) do { \
549 (o)->hndl=socketSocket(AF_INET, SOCK_DGRAM, 0); \
550 *(status) = HttpSocket_isValid(o) ? 0 : -1; \
553#define HttpSocket_sockUdp(o, interfNameNotUsed, useIp6, status) do { \
555 HttpSocket_sockUdpIp6(o, status); \
557 HttpSocket_sockUdpIp4(o, status); \
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);\
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);\
576#define HttpSocket_recvfromIp6(o,data,len,sockAddr,port,status) *status=-1
578#define HttpSocket_recvfrom(o,data,len,sockAddr,port,status) do { \
579 if((sockAddr)->isIp6) \
580 HttpSocket_recvfromIp6(o,data,len,sockAddr,port,status); \
582 HttpSocket_recvfromIp4(o,data,len,sockAddr,port,status); \
587#ifndef HttpSocket_setmembership
588BA_API
int HttpSocket_setmembership(HttpSocket* o,
591 const char* multiAddrName,
592 const char* intfName);
597#ifndef HttpSocket_wouldBlock
598#define HttpSocket_wouldBlock(o, status) do { \
599 *(status)=socketWouldBlock((o)->hndl); \
601 *(status)=socketInProgress((o)->hndl); \
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));
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)\
631 HttpSocket_connectV4(o, addrMA, port, status)\
635#define HttpSocket_connect(o, addr, port, status) do {\
636 HttpSocket_connectV4(o, addr, port, status) } while(0)
647BA_API
int HttpSocket_create(HttpSocket* o,
648 const char* bindIntfName,
653typedef struct HttpSockaddr {
659#ifndef HttpSockaddr_gethostbynameIp6
661#define HttpSockaddr_gethostbynameIp6(o, host, status) do { \
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) ) { \
670 &((struct sockaddr_in6*)servinfo->ai_addr)->sin6_addr, 16); \
671 freeaddrinfo(servinfo); \
675 memset((o)->addr, 0, 16); \
681#define HttpSockaddr_gethostbynameIp6(o, host, status) \
682 HttpSockaddr_gethostbynameIp4(o, host, status)
686#ifndef HttpSockaddr_gethostbyname
687#if BA_USE_GETADDRINFO
688#define HttpSockaddr_gethostbynameIp4(o, host, status) do { \
692 struct addrinfo hints, *result; \
693 memset(&hints, 0, sizeof(hints)); \
694 hints.ai_family=AF_INET; \
695 *(status)=getaddrinfo(host, 0, &hints, &result); \
697 memcpy((o)->addr, &((struct sockaddr_in*)result->ai_addr)->sin_addr, 4); \
698 freeaddrinfo(result); \
701 else memset((o)->addr, 0, 4); \
704#define HttpSockaddr_gethostbynameIp4(o, host, status) do { \
705 unsigned long ipAddr; \
710 ipAddr = socketInetAddr(host); \
711 if(ipAddr == INADDR_NONE) \
713 struct hostent* hostInfo = socketGethostbyname((char*)host); \
717 memcpy(&ipAddr,&((struct in_addr *)hostInfo->h_addr)->s_addr,4);\
721 ipAddr = baHtonl(INADDR_ANY); \
722 memcpy((o)->addr,&ipAddr, 4); \
728#define HttpSockaddr_gethostbyname(o, host, useIp6, status) do { \
730 HttpSockaddr_gethostbynameIp6(o, host, status); \
732 HttpSockaddr_gethostbynameIp4(o, host, status); \
737#ifndef HttpSockaddr_addr2String
738BA_API
void HttpSockaddr_addr2String(
739 HttpSockaddr* o,
char* buf,
int bufLen,
int* status);
743#ifndef HttpSockaddr_inetAddr
744BA_API
void HttpSockaddr_inetAddr(
745 HttpSockaddr* o,
const char* host,
BaBool useIp6,
int* status);
754#if BA_USE_GETADDRINFO
757typedef struct addrinfo BaAddrinfo;
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; \
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; \
775#ifndef BaAddrinfo_next
776#define BaAddrinfo_next(iter) *((iter)) = (*(iter))->ai_next
779#ifndef BaAddrinfo_free
780#define BaAddrinfo_free(addr) freeaddrinfo(addr)
783#ifndef BaAddrinfo_isIp6
784#define BaAddrinfo_isIp6(addr) (addr)->ai_family == AF_INET6
787#ifndef BaAddrinfo_connect
788int BaAddrinfo_connect(BaAddrinfo* addr, HttpSocket* s,
U32 timeout);
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)
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