DTS Application Library  0.2.3
Application library containing referenced objects and interfaces to common libraries
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Groups Pages
socket.c
Go to the documentation of this file.
1 /*
2 Copyright (C) 2012 Gregory Nietsky <gregory@distrotetch.co.za>
3  http://www.distrotech.co.za
4 
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9 
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18 
30 #ifndef __WIN32__
31 #include <netdb.h>
32 #endif
33 #include <unistd.h>
34 #include <stdint.h>
35 #include <string.h>
36 #include <errno.h>
37 #include <stdio.h>
38 #include <fcntl.h>
39 #ifdef __WIN32__
40 #include <winsock2.h>
41 #include <ws2tcpip.h>
42 #else
43 #include <arpa/inet.h>
44 #endif
45 #include <stdlib.h>
46 
47 #include "include/dtsapp.h"
48 #include "include/private.h"
49 
53  struct fwsocket *sock;
55  void *data;
64 };
65 
66 static int32_t hash_socket(const void *data, int key) {
67  int ret;
68  const struct fwsocket *sock = data;
69  const int *hashkey = (key) ? data : &sock->sock;
70 
71  ret = *hashkey;
72 
73  return (ret);
74 }
75 
79 extern void close_socket(struct fwsocket *sock) {
80  if (sock) {
81  setflag(sock, SOCK_FLAG_CLOSE);
82  objunref(sock);
83  }
84 }
85 
86 static void clean_fwsocket(void *data) {
87  struct fwsocket *sock = data;
88 
89  if (sock->ssl) {
90  objunref(sock->ssl);
91  }
92 
93  /*im closing remove from parent list*/
94  if (sock->parent) {
95  if (sock->parent->children) {
96  remove_bucket_item(sock->parent->children, sock);
97  }
98  objunref(sock->parent);
99  }
100 
101  /*looks like the server is shut down*/
102  if (sock->children) {
103  objunref(sock->children);
104  }
105 
106  if (sock->sock >= 0) {
107  close(sock->sock);
108  }
109 }
110 
120 extern struct fwsocket *make_socket(int family, int type, int proto, void *ssl) {
121  struct fwsocket *si;
122 
123  if (!(si = objalloc(sizeof(*si),clean_fwsocket))) {
124  return NULL;
125  }
126 
127  if ((si->sock = socket(family, type, proto)) < 0) {
128  objunref(si);
129  return NULL;
130  };
131 
132  if (ssl) {
133  si->ssl = ssl;
134  }
135  si->type = type;
136  si->proto = proto;
137 
138  return (si);
139 }
140 
144 extern struct fwsocket *accept_socket(struct fwsocket *sock) {
145  struct fwsocket *si;
146  socklen_t salen = sizeof(si->addr);
147 
148  if (!(si = objalloc(sizeof(*si),clean_fwsocket))) {
149  return NULL;
150  }
151 
152  objlock(sock);
153  if ((si->sock = accept(sock->sock, &si->addr.sa, &salen)) < 0) {
154  objunlock(sock);
155  objunref(si);
156  return NULL;
157  }
158 
159  si->type = sock->type;
160  si->proto = sock->proto;
161 
162  if (sock->ssl) {
163  tlsaccept(si, sock->ssl);
164  }
165  objunlock(sock);
166 
167  return (si);
168 }
169 
170 static struct fwsocket *_opensocket(int family, int stype, int proto, const char *ipaddr, const char *port, void *ssl, int ctype, int backlog) {
171  struct addrinfo hint, *result, *rp;
172  struct fwsocket *sock = NULL;
173  socklen_t salen = sizeof(union sockstruct);
174 #ifndef __WIN32__
175  int on = 1;
176 #endif
177 
178  memset(&hint, 0, sizeof(hint));
179  hint.ai_family = family;
180  hint.ai_socktype = stype;
181  hint.ai_protocol = proto;
182 
183  if (getaddrinfo(ipaddr, port, &hint, &result) || !result) {
184  return (NULL);
185  }
186 
187  for(rp = result; rp; rp = result->ai_next) {
188  if (!(sock = make_socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol, ssl))) {
189  continue;
190  }
191  if (ctype) {
192 #ifndef __WIN32__
193  setsockopt(sock->sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
194 #ifdef SO_REUSEPORT
195  setsockopt(sock->sock, SOL_SOCKET, SO_REUSEPORT, &on, sizeof(on));
196 #endif
197 #else
198 /* ioctlsocket(sock->sock, SO_REUSEADDR, (unsigned long*)&on);*/
199 #endif
200  }
201  if ((!ctype && !connect(sock->sock, rp->ai_addr, rp->ai_addrlen)) ||
202  (ctype && !bind(sock->sock, rp->ai_addr, rp->ai_addrlen))) {
203  break;
204  }
205  objunref(sock);
206  sock = NULL;
207  }
208 
209 
210  if (!sock || !rp) {
211  if (sock) {
212  objunref(sock);
213  }
214  freeaddrinfo(result);
215 
216  return (NULL);
217  }
218 
219 
220  if (ctype) {
221  sock->flags |= SOCK_FLAG_BIND;
222  memcpy(&sock->addr.ss, rp->ai_addr, sizeof(sock->addr.ss));
223  switch(sock->type) {
224  case SOCK_STREAM:
225  case SOCK_SEQPACKET:
226  listen(sock->sock, backlog);
227  /* no break */
228  default:
229  break;
230  }
231  } else {
232  getsockname(sock->sock, &sock->addr.sa, &salen);
233  }
234 
235  freeaddrinfo(result);
236  return (sock);
237 }
238 
250 extern struct fwsocket *sockconnect(int family, int stype, int proto, const char *ipaddr, const char *port, void *ssl) {
251  return(_opensocket(family, stype, proto, ipaddr, port, ssl, 0, 0));
252 }
253 
262 extern struct fwsocket *udpconnect(const char *ipaddr, const char *port, void *ssl) {
263  return (_opensocket(PF_UNSPEC, SOCK_DGRAM, IPPROTO_UDP, ipaddr, port, ssl, 0, 0));
264 }
265 
274 extern struct fwsocket *tcpconnect(const char *ipaddr, const char *port, void *ssl) {
275  return (_opensocket(PF_UNSPEC, SOCK_STREAM, IPPROTO_TCP, ipaddr, port, ssl, 0, 0));
276 }
277 
290 extern struct fwsocket *sockbind(int family, int stype, int proto, const char *ipaddr, const char *port, void *ssl, int backlog) {
291  return(_opensocket(family, stype, proto, ipaddr, port, ssl, 1, backlog));
292 }
293 
302 extern struct fwsocket *udpbind(const char *ipaddr, const char *port, void *ssl) {
303  return (_opensocket(PF_UNSPEC, SOCK_DGRAM, IPPROTO_UDP, ipaddr, port, ssl, 1, 0));
304 }
305 
315 extern struct fwsocket *tcpbind(const char *ipaddr, const char *port, void *ssl, int backlog) {
316  return (_opensocket(PF_UNSPEC, SOCK_STREAM, IPPROTO_TCP, ipaddr, port, ssl, 1, backlog));
317 }
318 
319 static void _socket_handler_clean(void *data) {
320  struct socket_handler *fwsel = data;
321 
322  /*call cleanup and remove refs to data*/
323  if (fwsel->cleanup) {
324  fwsel->cleanup(fwsel->data);
325  }
326  if (fwsel->data) {
327  objunref(fwsel->data);
328  }
329 }
330 
331 static void *_socket_handler(void *data) {
332  struct socket_handler *sockh = data;
333  struct fwsocket *sock = sockh->sock;
334  struct fwsocket *newsock;
335  struct timeval tv;
336  fd_set rd_set, act_set;
337  int selfd, sockfd, type, flags;
338  struct bucket_loop *bloop;
339 #ifdef __WIN32
340  int errcode;
341 #endif
342  objlock(sock);
343  FD_ZERO(&rd_set);
344  sockfd = sock->sock;
345  type = sock->type;
346  if ((sock->flags & SOCK_FLAG_BIND) && (sock->ssl || !(sock->type == SOCK_DGRAM))) {
347  flags = (SOCK_FLAG_BIND & sock->flags);
348  } else {
349  flags = 0;
350  }
351  FD_SET(sockfd, &rd_set);
352  objunlock(sock);
353 
354  while (framework_threadok() && !testflag(sock, SOCK_FLAG_CLOSE)) {
355  act_set = rd_set;
356  tv.tv_sec = 0;
357  tv.tv_usec = 20000;
358 
359  selfd = select(sockfd + 1, &act_set, NULL, NULL, &tv);
360 
361  /*returned due to interupt continue or timed out*/
362 #ifndef __WIN32
363  if ((selfd < 0 && errno == EINTR) || (!selfd)) {
364 #else
365  errcode = WSAGetLastError();
366  if (((selfd == SOCKET_ERROR) && (errcode == WSAEINTR)) || (!selfd)) {
367 #endif
368  if ((type == SOCK_DGRAM) && (flags & SOCK_FLAG_BIND)) {
369  dtlshandltimeout(sock);
370  }
371  continue;
372  } else if (selfd < 0) {
373  break;
374  }
375 
376  if (FD_ISSET(sockfd, &act_set)) {
377  if (flags & SOCK_FLAG_BIND) {
378  switch (type) {
379  case SOCK_STREAM:
380  case SOCK_SEQPACKET:
381  newsock = accept_socket(sock);
382  break;
383  case SOCK_DGRAM:
384  newsock = dtls_listenssl(sock);
385  break;
386  default:
387  newsock = NULL;
388  break;
389  }
390  if (newsock) {
391  objref(sock);
392  newsock->parent = sock;
393  addtobucket(sock->children, newsock);
394  socketclient(newsock, sockh->data, sockh->client, NULL);
395  if (sockh->connect) {
396  sockh->connect(newsock, sockh->data);
397  }
398  objunref(newsock); /*pass ref to thread*/
399  }
400  } else {
401  sockh->client(sockh->sock, sockh->data);
402  }
403  }
404  }
405 
406  if (sock->ssl) {
407  ssl_shutdown(sock->ssl, sock->sock);
408  }
409 
410  /*close children*/
411  if (sock->children) {
412  bloop = init_bucket_loop(sock->children);
413  while(bloop && (newsock = next_bucket_loop(bloop))) {
414  remove_bucket_loop(bloop);
415  objlock(newsock);
416  if (newsock->parent) {
417  objunref(newsock->parent);
418  newsock->parent = NULL;
419  }
420  objunlock(newsock);
421  close_socket(newsock); /*remove ref*/
422  }
423  objunref(bloop);
424  }
425 
426  objunref(sock);
427 
428  return NULL;
429 }
430 
431 static void _start_socket_handler(struct fwsocket *sock, socketrecv read,
432  socketrecv acceptfunc, threadcleanup cleanup, void *data) {
433  struct socket_handler *sockh;
434 
435  if (!sock || !read || !(sockh = objalloc(sizeof(*sockh), NULL))) {
436  return;
437  }
438 
439  sockh->sock = sock;
440  sockh->client = read;
441  sockh->cleanup = cleanup;
442  sockh->connect = acceptfunc;
443  sockh->data = data;
444 
445  /* grab ref for data and pass sockh*/
446  objref(data);
447  objref(sock);
448  framework_mkthread(_socket_handler, _socket_handler_clean, NULL, sockh, 0);
449  objunref(sockh);
450 }
451 
463 extern void socketserver(struct fwsocket *sock, socketrecv read,
464  socketrecv acceptfunc, threadcleanup cleanup, void *data) {
465 
466  objlock(sock);
467  if (sock->flags & SOCK_FLAG_BIND) {
468  if (sock->ssl || !(sock->type == SOCK_DGRAM)) {
469  sock->children = create_bucketlist(6, hash_socket);
470  }
471  if (sock->ssl && (sock->type == SOCK_DGRAM)) {
472  objunlock(sock);
473  dtsl_serveropts(sock);
474  } else {
475  objunlock(sock);
476  }
477  } else {
478  objunlock(sock);
479  }
480  _start_socket_handler(sock, read, acceptfunc, cleanup, data);
481 }
482 
493 extern void socketclient(struct fwsocket *sock, void *data, socketrecv read, threadcleanup cleanup) {
494  startsslclient(sock);
495 
496  _start_socket_handler(sock, read, NULL, cleanup, data);
497 }
498 
504 const char *sockaddr2ip(union sockstruct *addr, char *buff, int blen) {
505  if (!buff) {
506  return NULL;
507  }
508 
509  switch (addr->ss.ss_family) {
510  case PF_INET:
511  inet_ntop(PF_INET, &addr->sa4.sin_addr, buff, blen);
512  break;
513  case PF_INET6:
514  inet_ntop(PF_INET6, &addr->sa6.sin6_addr, buff, blen);
515  break;
516  }
517  return buff;
518 }
519 
536 struct fwsocket *mcast_socket(const char *iface, int family, const char *mcastip, const char *port, int flags) {
537  struct fwsocket *fws;
538  struct addrinfo hint, *result, *rp;
539  struct in_addr *srcif;
540  const char *srcip;
541  int ifidx;
542  int on = 1;
543  int off = 0;
544  int ttl = 50;
545  socklen_t slen = sizeof(union sockstruct);
546 #ifdef __WIN32
547  struct ifinfo *ifinf;
548 #endif
549 
550  memset(&hint, 0, sizeof(hint));
551  hint.ai_family = PF_UNSPEC;
552  hint.ai_socktype = SOCK_DGRAM;
553  hint.ai_protocol = IPPROTO_UDP;
554 
555 #ifndef __WIN32
556  if (!(srcip = get_ifipaddr(iface, family))) {
557  return NULL;
558  }
559 
560  if (getaddrinfo(srcip, port, &hint, &result) || !result) {
561  free((void*)srcip);
562  return NULL;
563  }
564  free((void*)srcip);
565 #else
566  if (!(ifinf = get_ifinfo(iface))) {
567  return NULL;
568  }
569  ifidx = ifinf->idx;
570 
571  srcip = (family == AF_INET) ? ifinf->ipv4addr : ifinf->ipv6addr;
572  if (!srcip || (getaddrinfo(srcip, port, &hint, &result) || !result)) {
573  objunref(ifinf);
574  return NULL;
575  }
576  objunref(ifinf);
577 #endif
578 
579  for(rp = result; rp; rp = result->ai_next) {
580  if (!(fws = make_socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol, NULL))) {
581  continue;
582  }
583  break;
584  }
585 
586  if (!rp || !fws) {
587  freeaddrinfo(result);
588  return NULL;
589  }
590 
591  if(setsockopt(fws->sock, SOL_SOCKET, SO_REUSEADDR, (char*)&on, sizeof(on))) {
592  objunref(fws);
593  freeaddrinfo(result);
594  return NULL;
595  }
596 
597  if (rp->ai_family == PF_INET) {
598  struct in_addr mcastip4;
599  struct ip_mreq mg;
600  struct sockaddr_in *src_ip;
601 
602  src_ip = (struct sockaddr_in*)rp->ai_addr;
603 
604  if (setsockopt(fws->sock, IPPROTO_IP, IP_MULTICAST_TTL, (char*)&ttl, sizeof(ttl))) {
605  objunref(fws);
606  freeaddrinfo(result);
607  return NULL;
608  }
609 
610  if (flags && setsockopt(fws->sock, IPPROTO_IP, IP_MULTICAST_LOOP, (char*)&off, sizeof(off))) {
611  freeaddrinfo(result);
612  objunref(fws);
613  return NULL;
614  }
615 
616  if (mcastip) {
617  inet_lookup(PF_INET, mcastip, &mcastip4, sizeof(mcastip4));
618  } else {
619  seedrand();
620  mcast4_ip(&mcastip4);
621  }
622 
623  mg.imr_multiaddr = mcastip4;
624  mg.imr_interface.s_addr = src_ip->sin_addr.s_addr;
625  if (setsockopt(fws->sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*)&mg, sizeof(mg))) {
626  objunref(fws);
627  freeaddrinfo(rp);
628  return NULL;
629  }
630 
631  memset(&srcif, 0, sizeof(srcif));
632  srcif = &src_ip->sin_addr;
633  if(setsockopt(fws->sock, IPPROTO_IP, IP_MULTICAST_IF, (char*)srcif, sizeof(*srcif))) {
634  freeaddrinfo(rp);
635  objunref(fws);
636  return NULL;
637  }
638  src_ip->sin_addr.s_addr = mcastip4.s_addr;
639  } else if (rp->ai_family == PF_INET6) {
640  struct in6_addr mcastip6;
641  struct ipv6_mreq mg;
642  struct sockaddr_in6 *src_ip;
643 
644 #ifndef __WIN32
645  ifidx = get_iface_index(iface);
646 #endif
647  src_ip = (struct sockaddr_in6*)rp->ai_addr;
648 
649  if (setsockopt(fws->sock, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (char*)&ttl, sizeof(ttl))) {
650  objunref(fws);
651  freeaddrinfo(result);
652  return NULL;
653  }
654 
655  if (flags && setsockopt(fws->sock, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, (char*)&off, sizeof(off))) {
656  freeaddrinfo(result);
657  objunref(fws);
658  return NULL;
659  }
660 
661  if (mcastip) {
662  inet_lookup(PF_INET6, mcastip, &mcastip6, sizeof(mcastip6));
663  } else {
664  seedrand();
665  mcast6_ip(&mcastip6);
666  }
667 
668  mg.ipv6mr_multiaddr = mcastip6;
669  mg.ipv6mr_interface = ifidx;
670  if (setsockopt(fws->sock, IPPROTO_IPV6, IPV6_JOIN_GROUP, (char*)&mg, sizeof(mg))) {
671  objunref(fws);
672  freeaddrinfo(rp);
673  return NULL;
674  }
675 
676  if (setsockopt(fws->sock, IPPROTO_IPV6, IPV6_MULTICAST_IF, (char*)&ifidx, sizeof(ifidx))) {
677  objref(fws);
678  freeaddrinfo(rp);
679  return NULL;
680  }
681 
682  src_ip->sin6_addr = mcastip6;
683  }
684 
685  if (bind(fws->sock, (struct sockaddr*)rp->ai_addr, sizeof(struct sockaddr_storage))) {
686  freeaddrinfo(result);
687  objunref(fws);
688  return NULL;
689  }
690 
691  getsockname(fws->sock, &fws->addr.sa, &slen);
692  freeaddrinfo(result);
693  fws->flags |= SOCK_FLAG_MCAST;
694 
695  return fws;
696 }
697 
698 
Bucket iterator.
Definition: refobj.c:97
struct fwsocket * sockbind(int family, int stype, int proto, const char *ipaddr, const char *port, void *ssl, int backlog)
Generic server socket.
Definition: socket.c:290
union sockstruct addr
system socket data structure.
Definition: dtsapp.h:143
void * create_bucketlist(int bitmask, blisthash hash_function)
Definition: refobj.c:356
const char * sockaddr2ip(union sockstruct *addr, char *buf, int len)
Return the ip address of a sockstruct addr.
Definition: socket.c:504
socketrecv client
Callback called when the socket is ready to read.
Definition: socket.c:57
void ssl_shutdown(void *ssl, int sock)
Shutdown the SSL connection.
Definition: sslutil.c:179
int objref(void *data)
Reference a object.
Definition: refobj.c:153
#define testflag(obj, flag)
Atomically test a flag in the flags field of a referenced object.
Definition: dtsapp.h:932
struct fwsocket * dtls_listenssl(struct fwsocket *sock)
Implementation of &quot;listen&quot; for DTLSv1.
Definition: sslutil.c:731
void mcast6_ip(struct in6_addr *addr)
Randomally assign a SSM Multicast address.param addr Ip address structure to fill out...
Definition: iputil.c:480
int inet_lookup(int family, const char *host, void *addr, socklen_t len)
Perform DNS lookup on a host/ip retun the IP address.
Definition: iputil.c:523
int objlock(void *data)
Lock the reference.
Definition: refobj.c:269
struct fwsocket * parent
Parent socket if we connected to a server and were spawned.
Definition: dtsapp.h:148
socketrecv connect
If a client connects to a bound port this callback is called on connect.
Definition: socket.c:63
Socket data structure.
Definition: dtsapp.h:131
struct fwsocket * tcpbind(const char *ipaddr, const char *port, void *ssl, int backlog)
Generic server socket.
Definition: socket.c:315
Multicast Socket.
Definition: dtsapp.h:112
void * data
Reference to data passed in callbacks.
Definition: socket.c:55
void dtlshandltimeout(struct fwsocket *sock)
Handle DTLSv1 timeout.
Definition: sslutil.c:846
void * objalloc(int size, objdestroy)
Allocate a referenced lockable object.
Definition: refobj.c:129
Data structure containing interface information.
Definition: dtsapp.h:176
int idx
Interface index required for at least IPv6 multicast support.
Definition: dtsapp.h:178
struct ifinfo * get_ifinfo(const char *iface)
Return interface info for a specified interface.
Definition: winiface.cpp:83
#define setflag(obj, flag)
Atomically set a flag in the flags field of a referenced object.
Definition: dtsapp.h:925
void * next_bucket_loop(struct bucket_loop *bloop)
Return a reference to the next item in the list this could be the first item.
Definition: refobj.c:662
int sock
Socket FD.
Definition: dtsapp.h:133
void close_socket(struct fwsocket *sock)
Mark the socket for closure and release the reference.
Definition: socket.c:79
const char * get_ifipaddr(const char *iface, int family)
Find best IP adress for a interface.
Definition: interface.c:783
Socket handling thread data.
Definition: socket.c:51
DTS Application library API Include file.
void(* socketrecv)(struct fwsocket *, void *)
Callback function to register with a socket that will be called when there is data available...
Definition: dtsapp.h:259
int get_iface_index(const char *ifname)
Get the netlink interface for a named interface.
Definition: interface.c:139
const char * ipv6addr
IPv6 address priorised by Local/6in4.
Definition: dtsapp.h:184
void tlsaccept(struct fwsocket *sock, struct ssldata *orig)
Create SSL session for new connection.
Definition: sslutil.c:382
void startsslclient(struct fwsocket *sock)
Start SSL on a client socket.
Definition: sslutil.c:811
The socket has been bound and awaiting connections.
Definition: dtsapp.h:104
const char * ipv4addr
IPv4 address priorotised by Routed/Reserved/Zeroconf.
Definition: dtsapp.h:182
struct thread_pvt * framework_mkthread(threadfunc, threadcleanup, threadsighandler, void *data, int flags)
create a thread result must be unreferenced
Definition: thread.c:387
struct bucket_list * children
We are the parent this is a list of spawn.
Definition: dtsapp.h:150
int proto
Socket protocol.
Definition: dtsapp.h:135
struct ssldata * ssl
SSL structure for encryption.
Definition: dtsapp.h:146
struct fwsocket * udpconnect(const char *ipaddr, const char *port, void *ssl)
UDP Socket client.
Definition: socket.c:262
struct sockaddr_in sa4
IPv4 socket addr structure.
Definition: dtsapp.h:88
void socketserver(struct fwsocket *sock, socketrecv connectfunc, socketrecv acceptfunc, threadcleanup cleanup, void *data)
Create a server thread with a socket that has been created with sockbind udpbind or tcpbind...
Definition: socket.c:463
struct fwsocket * make_socket(int family, int type, int proto, void *ssl)
Allocate a socket structure and return reference.
Definition: socket.c:120
int objunlock(void *data)
Unlock a reference.
Definition: refobj.c:301
void seedrand(void)
Seed openssl random number generator.
Definition: util.c:68
struct sockaddr_storage ss
Sockaddr storage is a &quot;magic&quot; struct been able to hold IPv4 or IPv6.
Definition: dtsapp.h:92
int framework_threadok(void)
let threads check there status.
Definition: thread.c:143
struct fwsocket * sock
Socket this thread manages.
Definition: socket.c:53
struct fwsocket * udpbind(const char *ipaddr, const char *port, void *ssl)
UDP server socket.
Definition: socket.c:302
void socketclient(struct fwsocket *sock, void *data, socketrecv read, threadcleanup cleanup)
Create a server thread with a socket that has been created with sockbind udpbind or tcpbind...
Definition: socket.c:493
struct fwsocket * mcast_socket(const char *iface, int family, const char *mcastip, const char *port, int flags)
Create a multicast socket.
Definition: socket.c:536
void(* threadcleanup)(void *)
Function called after thread termination.
Definition: dtsapp.h:238
threadcleanup cleanup
Callback to call when the thread closes to allow additional cleanup.
Definition: socket.c:60
struct fwsocket * sockconnect(int family, int stype, int proto, const char *ipaddr, const char *port, void *ssl)
Generic client socket.
Definition: socket.c:250
struct sockaddr sa
Base socket addr structure.
Definition: dtsapp.h:82
int type
Socket type.
Definition: dtsapp.h:137
void mcast4_ip(struct in_addr *addr)
Randomally assign a SSM Multicast address.
Definition: iputil.c:504
void remove_bucket_loop(struct bucket_loop *bloop)
Safely remove a item from a list while iterating in a loop.
Definition: refobj.c:710
void dtsl_serveropts(struct fwsocket *sock)
Start up the DTLSv1 Server.
Definition: sslutil.c:685
struct fwsocket * accept_socket(struct fwsocket *sock)
Create and return a socket structure from accept()
Definition: socket.c:144
const char * inet_ntop(int af, const void *src, char *dest, socklen_t size)
Win32 implementation of inet_ntop.
Definition: winiface.cpp:43
int addtobucket(struct bucket_list *blist, void *data)
Add a reference to the bucketlist.
Definition: refobj.c:428
void remove_bucket_item(struct bucket_list *blist, void *data)
Remove and unreference a item from the list.
Definition: refobj.c:517
struct sockaddr_in6 sa6
IPv6 socket addr structure.
Definition: dtsapp.h:90
Socket union describing all address types.
Definition: dtsapp.h:80
enum sock_flags flags
Socket control flags.
Definition: dtsapp.h:140
int objunref(void *data)
Drop reference held.
Definition: refobj.c:184
struct fwsocket * tcpconnect(const char *ipaddr, const char *port, void *ssl)
TCP Socket client.
Definition: socket.c:274
struct bucket_loop * init_bucket_loop(struct bucket_list *blist)
Create a bucket list iterator to safely iterate the list.
Definition: refobj.c:640
The socket is going away stop processing in its thread.
Definition: dtsapp.h:106