00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef SU_H
00026
00027 #define SU_H
00028
00036
00037
00038
00039 #ifndef SU_CONFIG_H
00040 #include "sofia-sip/su_config.h"
00041 #endif
00042 #ifndef SU_TYPES_H
00043 #include "sofia-sip/su_types.h"
00044 #endif
00045 #ifndef SU_ERRNO_H
00046 #include <sofia-sip/su_errno.h>
00047 #endif
00048
00049 #include <stdio.h>
00050 #include <limits.h>
00051
00052 #if SU_HAVE_BSDSOCK
00053 #include <errno.h>
00054 #include <unistd.h>
00055
00056 #include <fcntl.h>
00057 #include <sys/types.h>
00058 #include <sys/socket.h>
00059 #include <sys/ioctl.h>
00060
00061 #include <netinet/in.h>
00062 #include <arpa/inet.h>
00063 #include <netdb.h>
00064 #endif
00065
00066 #if SU_HAVE_WINSOCK
00067 # include <winsock2.h>
00068 # include <ws2tcpip.h>
00069
00070 # if defined(IPPROTO_IPV6)
00071
00072 # elif SU_HAVE_IN6
00073 # include <tpipv6.h>
00074 # else
00075 # error Winsock with IPv6 support required
00076 # endif
00077
00078 #endif
00079
00080 SOFIA_BEGIN_DECLS
00081
00082
00083
00084
00085 #if SU_HAVE_BSDSOCK || DOCUMENTATION_ONLY
00086 enum {
00088 INVALID_SOCKET = -1,
00089 #define INVALID_SOCKET ((su_socket_t)INVALID_SOCKET)
00090
00091 SOCKET_ERROR = -1,
00092 #define SOCKET_ERROR SOCKET_ERROR
00093
00094 su_success = 0,
00096 su_failure = -1
00097 };
00098 #elif SU_HAVE_WINSOCK
00099 enum {
00100 su_success = 0,
00101 su_failure = 0xffffffffUL
00102 };
00103
00104 #define MSG_NOSIGNAL (0)
00105
00106 #endif
00107
00109 #define SU_MAXHOST (1025)
00110
00111 #define SU_MAXSERV (25)
00112
00114 #define SU_ADDRSIZE (48)
00115
00116 #define SU_SERVSIZE (16)
00117
00118 #define SU_SUCCESS su_success
00119 #define SU_FAILURE su_failure
00120
00121
00122
00123
00125 #if SU_HAVE_BSDSOCK || DOCUMENTATION_ONLY
00126 typedef int su_socket_t;
00127 #elif SU_HAVE_WINSOCK
00128 typedef SOCKET su_socket_t;
00129 #endif
00130
00131 #if !SU_HAVE_SOCKADDR_STORAGE
00132
00133
00134
00135 #define _SS_MAXSIZE 128
00136 #define _SS_ALIGNSIZE (sizeof(int64_t))
00137 #define _SS_PAD1SIZE (_SS_ALIGNSIZE - sizeof(u_char) * 2)
00138 #define _SS_PAD2SIZE (_SS_MAXSIZE - sizeof(u_char) * 2 - \
00139 _SS_PAD1SIZE - _SS_ALIGNSIZE)
00140
00141 struct sockaddr_storage {
00142 #if SU_HAVE_SOCKADDR_SA_LEN
00143 unsigned char ss_len;
00144 unsigned char ss_family;
00145 #else
00146 unsigned short ss_family;
00147 #endif
00148 char __ss_pad1[_SS_PAD1SIZE];
00149 int64_t __ss_align;
00150 char __ss_pad2[_SS_PAD2SIZE];
00151 };
00152 #endif
00153
00155 union su_sockaddr_u {
00156 #ifdef DOCUMENTATION_ONLY
00157 uint8_t su_len;
00158 uint8_t su_family;
00159 uint16_t su_port;
00160 #else
00161 short su_dummy;
00162 #if SU_HAVE_SOCKADDR_SA_LEN
00163 #define su_len su_sa.sa_len
00164 #define su_family su_sa.sa_family
00165 #else
00166 #define su_len su_array[0]
00167 short su_family;
00168 #endif
00169 #define su_port su_sin.sin_port
00170 #endif
00171
00172 char su_array[32];
00173 uint16_t su_array16[16];
00174 uint32_t su_array32[8];
00175 struct sockaddr su_sa;
00176 struct sockaddr_in su_sin;
00177 #if SU_HAVE_IN6
00178 struct sockaddr_in6 su_sin6;
00179 #endif
00180 #ifdef DOCUMENTATION_ONLY
00181 uint32_t su_scope_id;
00182 #else
00183 #define su_scope_id su_array32[6]
00184 #endif
00185 };
00186
00187 typedef union su_sockaddr_u su_sockaddr_t;
00188
00189 #if SU_HAVE_BSDSOCK || DOCUMENTATION_ONLY
00190
00200 typedef size_t su_ioveclen_t;
00201
00238 typedef struct su_iovec_s {
00239 void *siv_base;
00240 su_ioveclen_t siv_len;
00241 } su_iovec_t;
00242
00249 #define SU_IOVECLEN_MAX SIZE_MAX
00250 #endif
00251
00252 #if SU_HAVE_WINSOCK
00253 typedef u_long su_ioveclen_t;
00254
00255
00256 typedef struct su_iovec_s {
00257 su_ioveclen_t siv_len;
00258 void *siv_base;
00259 } su_iovec_t;
00260
00261 #define SU_IOVECLEN_MAX ULONG_MAX
00262 #endif
00263
00264
00265
00266
00267 SOFIAPUBFUN int su_init(void);
00268 SOFIAPUBFUN void su_deinit(void);
00269
00271 SOFIAPUBFUN su_socket_t su_socket(int af, int sock, int proto);
00273 SOFIAPUBFUN int su_close(su_socket_t s);
00275 SOFIAPUBFUN int su_ioctl(su_socket_t s, int request, ...);
00276
00284 SOFIAPUBFUN int su_is_blocking(int errcode);
00285
00287 SOFIAPUBFUN int su_setblocking(su_socket_t s, int blocking);
00289 SOFIAPUBFUN int su_setreuseaddr(su_socket_t s, int reuse);
00291 SOFIAPUBFUN int su_soerror(su_socket_t s);
00293 SOFIAPUBFUN issize_t su_getmsgsize(su_socket_t s);
00294
00296 SOFIAPUBFUN
00297 issize_t su_vsend(su_socket_t, su_iovec_t const iov[], isize_t len, int flags,
00298 su_sockaddr_t const *su, socklen_t sulen);
00300 SOFIAPUBFUN
00301 issize_t su_vrecv(su_socket_t, su_iovec_t iov[], isize_t len, int flags,
00302 su_sockaddr_t *su, socklen_t *sulen);
00304 SOFIAPUBFUN int su_getlocalip(su_sockaddr_t *sin);
00305
00306 #if SU_HAVE_BSDSOCK
00307 #define su_ioctl ioctl
00308
00309
00310
00311
00312 #define su_is_blocking(e) \
00313 ((e) == EINPROGRESS || (e) == EAGAIN || (e) == EWOULDBLOCK)
00314 #endif
00315
00316 #if SU_HAVE_WINSOCK
00317 SOFIAPUBFUN int inet_pton(int af, char const *src, void *dst);
00318 SOFIAPUBFUN const char *inet_ntop(int af, void const *src,
00319 char *dst, size_t size);
00320 SOFIAPUBFUN ssize_t
00321 su_send(su_socket_t s, void *buffer, size_t length, int flags),
00322 su_sendto(su_socket_t s, void *buffer, size_t length, int flags,
00323 su_sockaddr_t const *to, socklen_t tolen),
00324 su_recv(su_socket_t s, void *buffer, size_t length, int flags),
00325 su_recvfrom(su_socket_t s, void *buffer, size_t length, int flags,
00326 su_sockaddr_t *from, socklen_t *fromlen);
00327
00328 static __inline
00329 uint16_t su_ntohs(uint16_t s)
00330 {
00331 return (uint16_t)(((s & 255) << 8) | ((s & 0xff00) >> 8));
00332 }
00333
00334 static __inline
00335 uint32_t su_ntohl(uint32_t l)
00336 {
00337 return ((l & 0xff) << 24) | ((l & 0xff00) << 8)
00338 | ((l & 0xff0000) >> 8) | ((l & 0xff000000U) >> 24);
00339 }
00340
00341 #define ntohs su_ntohs
00342 #define htons su_ntohs
00343 #define ntohl su_ntohl
00344 #define htonl su_ntohl
00345
00346 #else
00347 #define su_send(s,b,l,f) send((s),(b),(l),(f))
00348 #define su_sendto(s,b,l,f,a,L) sendto((s),(b),(l),(f),(void const*)(a),(L))
00349 #define su_recv(s,b,l,f) recv((s),(b),(l),(f))
00350 #define su_recvfrom(s,b,l,f,a,L) recvfrom((s),(b),(l),(f),(void *)(a),(L))
00351 #endif
00352
00353
00354
00355
00356 #if SU_HAVE_WINSOCK
00357 #define getuid() (0x505)
00358 #endif
00359
00360 #ifndef IPPROTO_SCTP
00361 #define IPPROTO_SCTP (132)
00362 #endif
00363
00364
00365
00366
00372 #if SU_HAVE_IN6
00373 #define SU_ADDR(su) \
00374 ((su)->su_family == AF_INET ? (void *)&(su)->su_sin.sin_addr : \
00375 ((su)->su_family == AF_INET6 ? (void *)&(su)->su_sin6.sin6_addr : \
00376 (void *)&(su)->su_sa.sa_data))
00377 #else
00378 #define SU_ADDR(su) \
00379 ((su)->su_family == AF_INET ? (void *)&(su)->su_sin.sin_addr : \
00380 (void *)&(su)->su_sa.sa_data)
00381 #endif
00382
00388 #if SU_HAVE_IN6
00389 #define SU_ADDRLEN(su) \
00390 ((su)->su_family == AF_INET \
00391 ? (socklen_t)sizeof((su)->su_sin.sin_addr) : \
00392 ((su)->su_family == AF_INET6 \
00393 ? (socklen_t)sizeof((su)->su_sin6.sin6_addr) \
00394 : (socklen_t)sizeof((su)->su_sa.sa_data)))
00395 #else
00396 #define SU_ADDRLEN(su) \
00397 ((su)->su_family == AF_INET \
00398 ? (socklen_t)sizeof((su)->su_sin.sin_addr) \
00399 : (socklen_t)sizeof((su)->su_sa.sa_data))
00400 #endif
00401
00403 #if SU_HAVE_IN6
00404 #define SU_HAS_INADDR_ANY(su) \
00405 ((su)->su_family == AF_INET \
00406 ? ((su)->su_sin.sin_addr.s_addr == INADDR_ANY) \
00407 : ((su)->su_family == AF_INET6 \
00408 ? (memcmp(&(su)->su_sin6.sin6_addr, su_in6addr_any(), \
00409 sizeof(*su_in6addr_any())) == 0) : 0))
00410 #else
00411 #define SU_HAS_INADDR_ANY(su) \
00412 ((su)->su_family == AF_INET \
00413 ? ((su)->su_sin.sin_addr.s_addr == INADDR_ANY) : 0)
00414 #endif
00415
00416 #define SU_SOCKADDR_INADDR_ANY(su) SU_HAS_INADDR_ANY(su)
00417
00419 #if SU_HAVE_IN6
00420 #define SU_SOCKADDR_SIZE(su) \
00421 ((socklen_t)((su)->su_family == AF_INET ? sizeof((su)->su_sin) \
00422 : ((su)->su_family == AF_INET6 ? sizeof((su)->su_sin6) \
00423 : sizeof(*su))))
00424 #else
00425 #define SU_SOCKADDR_SIZE(su) \
00426 ((socklen_t)((su)->su_family == AF_INET ? sizeof((su)->su_sin) \
00427 : sizeof(*su)))
00428 #endif
00429 #define su_sockaddr_size SU_SOCKADDR_SIZE
00430
00431 #if SU_HAVE_IN6
00432 #if SU_HAVE_BSDSOCK
00433 #define su_in6addr_any() (&in6addr_any)
00434 #define su_in6addr_loopback() (&in6addr_loopback)
00435 #define SU_IN6ADDR_ANY_INIT IN6ADDR_ANY_INIT
00436 #define SU_IN6ADDR_LOOPBACK_INIT IN6ADDR_LOOPBACK_INIT
00437 #endif
00438 #if SU_HAVE_WINSOCK || DOCUMENTATION_ONLY
00439 SOFIAPUBVAR const struct in_addr6 *su_in6addr_any(void);
00440 SOFIAPUBVAR const struct in_addr6 *su_in6addr_loopback(void);
00441 #define SU_IN6ADDR_ANY_INIT { 0 }
00442 #define SU_IN6ADDR_LOOPBACK_INIT { 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,1 }
00443 #endif
00444 #endif
00445
00446 #define SU_IN6_IS_ADDR_V4MAPPED(a) \
00447 (((uint32_t const *) (a))[0] == 0 && \
00448 ((uint32_t const *) (a))[1] == 0 && \
00449 ((uint32_t const *) (a))[2] == htonl(0xffff))
00450
00451 #define SU_IN6_IS_ADDR_V4COMPAT(a) \
00452 (((uint32_t const *)(a))[0] == 0 && \
00453 ((uint32_t const *)(a))[1] == 0 && \
00454 ((uint32_t const *)(a))[2] == 0 && \
00455 ((uint32_t const *)(a))[3] != htonl(1) && \
00456 ((uint32_t const *)(a))[3] != htonl(0))
00457
00458 SOFIAPUBFUN int su_cmp_sockaddr(su_sockaddr_t const *a,
00459 su_sockaddr_t const *b);
00460 SOFIAPUBFUN int su_match_sockaddr(su_sockaddr_t const *a,
00461 su_sockaddr_t const *b);
00462 SOFIAPUBFUN void su_canonize_sockaddr(su_sockaddr_t *su);
00463
00464 #if SU_HAVE_IN6
00465 #define SU_CANONIZE_SOCKADDR(su) \
00466 ((su)->su_family == AF_INET6 ? su_canonize_sockaddr(su) : (void)0)
00467 #else
00468 #define SU_CANONIZE_SOCKADDR(su) \
00469 ((void)0)
00470 #endif
00471
00472 SOFIA_END_DECLS
00473
00474 #ifndef SU_ADDRINFO_H
00475 #include <sofia-sip/su_addrinfo.h>
00476 #endif
00477
00478 #endif