su 1.12.11devel
|
00001 /* 00002 * This file is part of the Sofia-SIP package 00003 * 00004 * Copyright (C) 2005,2006,2007 Nokia Corporation. 00005 * 00006 * Contact: Pekka Pessi <pekka.pessi@nokia-email.address.hidden> 00007 * 00008 * This library is free software; you can redistribute it and/or 00009 * modify it under the terms of the GNU Lesser General Public License 00010 * as published by the Free Software Foundation; either version 2.1 of 00011 * the License, or (at your option) any later version. 00012 * 00013 * This library is distributed in the hope that it will be useful, but 00014 * WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00016 * Lesser General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU Lesser General Public 00019 * License along with this library; if not, write to the Free Software 00020 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 00021 * 02110-1301 USA 00022 * 00023 */ 00024 00025 #ifndef SU_H 00026 00027 #define SU_H 00028 00036 /* ---------------------------------------------------------------------- */ 00037 /* Includes */ 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 /* Unix-compatible includes */ 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 /* Windows includes */ 00067 # include <winsock2.h> 00068 # include <ws2tcpip.h> 00069 # if SU_HAVE_IN6 00070 # if defined(IPPROTO_IPV6) || (_WIN32_WINNT >= 0x0501) 00071 /* case 1: IPv6 defined in winsock2.h/ws2tcpip.h */ 00072 # else 00073 /* case 2: try to use "IPv6 Tech Preview" */ 00074 # include <tpipv6.h> 00075 # endif 00076 # endif 00077 #endif 00078 00079 SOFIA_BEGIN_DECLS 00080 00081 /* ---------------------------------------------------------------------- */ 00082 /* Constant definitions */ 00083 00084 #if SU_HAVE_BSDSOCK || DOCUMENTATION_ONLY 00085 enum { 00087 INVALID_SOCKET = -1, 00088 #define INVALID_SOCKET ((su_socket_t)INVALID_SOCKET) 00089 00090 SOCKET_ERROR = -1, 00091 #define SOCKET_ERROR SOCKET_ERROR 00092 00093 su_success = 0, 00095 su_failure = -1 00096 }; 00097 #if SYMBIAN && !defined(MSG_NOSIGNAL) 00098 #define MSG_NOSIGNAL (0) 00099 #endif 00100 #elif SU_HAVE_WINSOCK 00101 enum { 00102 su_success = 0, 00103 su_failure = 0xffffffffUL 00104 }; 00105 00106 #define MSG_NOSIGNAL (0) 00107 00108 #endif 00109 00111 #define SU_MAXHOST (1025) 00112 00113 #define SU_MAXSERV (25) 00114 00116 #define SU_ADDRSIZE (48) 00117 00118 #define SU_SERVSIZE (16) 00119 00120 #define SU_SUCCESS su_success 00121 #define SU_FAILURE su_failure 00122 00123 /* ---------------------------------------------------------------------- */ 00124 /* Type definitions */ 00125 00127 #if SU_HAVE_BSDSOCK || DOCUMENTATION_ONLY 00128 typedef int su_socket_t; 00129 #elif SU_HAVE_WINSOCK 00130 typedef SOCKET su_socket_t; 00131 #endif 00132 00133 #if !SU_HAVE_SOCKADDR_STORAGE 00134 /* 00135 * RFC 2553: protocol-independent placeholder for socket addresses 00136 */ 00137 #define _SS_MAXSIZE 128 00138 #define _SS_ALIGNSIZE (sizeof(int64_t)) 00139 #define _SS_PAD1SIZE (_SS_ALIGNSIZE - sizeof(u_char) * 2) 00140 #define _SS_PAD2SIZE (_SS_MAXSIZE - sizeof(u_char) * 2 - \ 00141 _SS_PAD1SIZE - _SS_ALIGNSIZE) 00142 00143 struct sockaddr_storage { 00144 #if SU_HAVE_SOCKADDR_SA_LEN 00145 unsigned char ss_len; /* address length */ 00146 unsigned char ss_family; /* address family */ 00147 #else 00148 unsigned short ss_family; /* address family */ 00149 #endif 00150 char __ss_pad1[_SS_PAD1SIZE]; 00151 int64_t __ss_align; /* force desired structure storage alignment */ 00152 char __ss_pad2[_SS_PAD2SIZE]; 00153 }; 00154 #endif 00155 00157 union su_sockaddr_u { 00158 #ifdef DOCUMENTATION_ONLY 00159 uint8_t su_len; 00160 uint8_t su_family; 00161 uint16_t su_port; 00162 #else 00163 short su_dummy; 00164 #if SU_HAVE_SOCKADDR_SA_LEN 00165 #define su_len su_sa.sa_len 00166 #else 00167 #define su_len su_array[0] 00168 #endif 00169 #define su_family su_sa.sa_family 00170 #define su_port su_sin.sin_port 00171 #endif 00172 00173 char su_array[32]; 00174 uint16_t su_array16[16]; 00175 uint32_t su_array32[8]; 00176 struct sockaddr su_sa; 00177 struct sockaddr_in su_sin; 00178 #if SU_HAVE_IN6 00179 struct sockaddr_in6 su_sin6; 00180 #endif 00181 #ifdef DOCUMENTATION_ONLY 00182 uint32_t su_scope_id; 00183 #else 00184 #define su_scope_id su_array32[6] 00185 #endif 00186 }; 00187 00188 typedef union su_sockaddr_u su_sockaddr_t; 00189 00190 #if SU_HAVE_BSDSOCK || DOCUMENTATION_ONLY 00191 00201 typedef size_t su_ioveclen_t; 00202 00239 typedef struct su_iovec_s { 00240 void *siv_base; 00241 su_ioveclen_t siv_len; 00242 } su_iovec_t; 00243 00250 #define SU_IOVECLEN_MAX SIZE_MAX 00251 #endif 00252 00253 #if SU_HAVE_WINSOCK 00254 typedef u_long su_ioveclen_t; 00255 00256 /* This is same as WSABUF */ 00257 typedef struct su_iovec_s { 00258 su_ioveclen_t siv_len; 00259 void *siv_base; 00260 } su_iovec_t; 00261 00262 #define SU_IOVECLEN_MAX ULONG_MAX 00263 #endif 00264 00265 /* ---------------------------------------------------------------------- */ 00266 /* Socket compatibility functions */ 00267 00268 SOFIAPUBFUN int su_init(void); 00269 SOFIAPUBFUN void su_deinit(void); 00270 00272 SOFIAPUBFUN su_socket_t su_socket(int af, int sock, int proto); 00274 SOFIAPUBFUN int su_close(su_socket_t s); 00276 SOFIAPUBFUN int su_ioctl(su_socket_t s, int request, ...); 00277 00287 SOFIAPUBFUN int su_is_blocking(int errcode); 00288 00290 SOFIAPUBFUN int su_setblocking(su_socket_t s, int blocking); 00292 SOFIAPUBFUN int su_setreuseaddr(su_socket_t s, int reuse); 00294 SOFIAPUBFUN int su_soerror(su_socket_t s); 00296 SOFIAPUBFUN int su_getsocktype(su_socket_t s); 00297 00299 SOFIAPUBFUN issize_t su_getmsgsize(su_socket_t s); 00300 00302 SOFIAPUBFUN 00303 issize_t su_vsend(su_socket_t, su_iovec_t const iov[], isize_t len, int flags, 00304 su_sockaddr_t const *su, socklen_t sulen); 00306 SOFIAPUBFUN 00307 issize_t su_vrecv(su_socket_t, su_iovec_t iov[], isize_t len, int flags, 00308 su_sockaddr_t *su, socklen_t *sulen); 00310 SOFIAPUBFUN int su_getlocalip(su_sockaddr_t *sin); 00311 00312 #if SU_HAVE_BSDSOCK 00313 #define su_ioctl ioctl 00314 /* 00315 * Note: before 1.12.2, there was su_isblocking() which did not take argument 00316 * and which was missing from WINSOCK 00317 */ 00318 #define su_is_blocking(e) \ 00319 ((e) == EINPROGRESS || (e) == EAGAIN || (e) == EWOULDBLOCK) 00320 #endif 00321 00322 #if SU_HAVE_WINSOCK 00323 SOFIAPUBFUN int su_inet_pton(int af, char const *src, void *dst); 00324 SOFIAPUBFUN const char *su_inet_ntop(int af, void const *src, 00325 char *dst, size_t size); 00326 SOFIAPUBFUN ssize_t 00327 su_send(su_socket_t s, void *buffer, size_t length, int flags), 00328 su_sendto(su_socket_t s, void *buffer, size_t length, int flags, 00329 su_sockaddr_t const *to, socklen_t tolen), 00330 su_recv(su_socket_t s, void *buffer, size_t length, int flags), 00331 su_recvfrom(su_socket_t s, void *buffer, size_t length, int flags, 00332 su_sockaddr_t *from, socklen_t *fromlen); 00333 00334 static __inline 00335 uint16_t su_ntohs(uint16_t s) 00336 { 00337 return (uint16_t)(((s & 255) << 8) | ((s & 0xff00) >> 8)); 00338 } 00339 00340 static __inline 00341 uint32_t su_ntohl(uint32_t l) 00342 { 00343 return ((l & 0xff) << 24) | ((l & 0xff00) << 8) 00344 | ((l & 0xff0000) >> 8) | ((l & 0xff000000U) >> 24); 00345 } 00346 00347 #define ntohs su_ntohs 00348 #define htons su_ntohs 00349 #define ntohl su_ntohl 00350 #define htonl su_ntohl 00351 00352 #else 00353 #define su_inet_pton inet_pton 00354 #define su_inet_ntop inet_ntop 00355 #define su_send(s,b,l,f) send((s),(b),(l),(f)) 00356 #define su_sendto(s,b,l,f,a,L) sendto((s),(b),(l),(f),(void const*)(a),(L)) 00357 #define su_recv(s,b,l,f) recv((s),(b),(l),(f)) 00358 #define su_recvfrom(s,b,l,f,a,L) recvfrom((s),(b),(l),(f),(void *)(a),(L)) 00359 #endif 00360 00361 /* ---------------------------------------------------------------------- */ 00362 /* Other compatibility stuff */ 00363 00364 #if SU_HAVE_WINSOCK 00365 #define getuid() (0x505) 00366 #endif 00367 00368 #ifndef IPPROTO_SCTP 00369 #define IPPROTO_SCTP (132) 00370 #endif 00371 00372 /* ---------------------------------------------------------------------- */ 00373 /* Address manipulation macros */ 00374 00380 #if SU_HAVE_IN6 00381 #define SU_ADDR(su) \ 00382 ((su)->su_family == AF_INET ? (void *)&(su)->su_sin.sin_addr : \ 00383 ((su)->su_family == AF_INET6 ? (void *)&(su)->su_sin6.sin6_addr : \ 00384 (void *)&(su)->su_sa.sa_data)) 00385 #else 00386 #define SU_ADDR(su) \ 00387 ((su)->su_family == AF_INET ? (void *)&(su)->su_sin.sin_addr : \ 00388 (void *)&(su)->su_sa.sa_data) 00389 #endif 00390 00396 #if SU_HAVE_IN6 00397 #define SU_ADDRLEN(su) \ 00398 ((su)->su_family == AF_INET \ 00399 ? (socklen_t)sizeof((su)->su_sin.sin_addr) : \ 00400 ((su)->su_family == AF_INET6 \ 00401 ? (socklen_t)sizeof((su)->su_sin6.sin6_addr) \ 00402 : (socklen_t)sizeof((su)->su_sa.sa_data))) 00403 #else 00404 #define SU_ADDRLEN(su) \ 00405 ((su)->su_family == AF_INET \ 00406 ? (socklen_t)sizeof((su)->su_sin.sin_addr) \ 00407 : (socklen_t)sizeof((su)->su_sa.sa_data)) 00408 #endif 00409 00411 #if SU_HAVE_IN6 00412 #define SU_HAS_INADDR_ANY(su) \ 00413 ((su)->su_family == AF_INET \ 00414 ? ((su)->su_sin.sin_addr.s_addr == INADDR_ANY) \ 00415 : ((su)->su_family == AF_INET6 \ 00416 ? (memcmp(&(su)->su_sin6.sin6_addr, su_in6addr_any(), \ 00417 sizeof(*su_in6addr_any())) == 0) : 0)) 00418 #else 00419 #define SU_HAS_INADDR_ANY(su) \ 00420 ((su)->su_family == AF_INET \ 00421 ? ((su)->su_sin.sin_addr.s_addr == INADDR_ANY) : 0) 00422 #endif 00423 00424 #define SU_SOCKADDR_INADDR_ANY(su) SU_HAS_INADDR_ANY(su) 00425 00427 #if SU_HAVE_IN6 00428 #define SU_SOCKADDR_SIZE(su) \ 00429 ((socklen_t)((su)->su_family == AF_INET ? sizeof((su)->su_sin) \ 00430 : ((su)->su_family == AF_INET6 ? sizeof((su)->su_sin6) \ 00431 : sizeof(*su)))) 00432 #else 00433 #define SU_SOCKADDR_SIZE(su) \ 00434 ((socklen_t)((su)->su_family == AF_INET ? sizeof((su)->su_sin) \ 00435 : sizeof(*su))) 00436 #endif 00437 #define su_sockaddr_size SU_SOCKADDR_SIZE 00438 00439 #if SU_HAVE_IN6 00440 #if SU_HAVE_BSDSOCK 00441 #define su_in6addr_any() (&in6addr_any) 00442 #define su_in6addr_loopback() (&in6addr_loopback) 00443 #define SU_IN6ADDR_ANY_INIT IN6ADDR_ANY_INIT 00444 #define SU_IN6ADDR_LOOPBACK_INIT IN6ADDR_LOOPBACK_INIT 00445 #endif 00446 #if SU_HAVE_WINSOCK || DOCUMENTATION_ONLY 00447 SOFIAPUBVAR const struct in_addr6 *su_in6addr_any(void); 00448 SOFIAPUBVAR const struct in_addr6 *su_in6addr_loopback(void); 00449 #define SU_IN6ADDR_ANY_INIT { 0 } 00450 #define SU_IN6ADDR_LOOPBACK_INIT { 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,1 } 00451 #endif 00452 #endif /* SU_HAVE_IN6 */ 00453 00454 #define SU_IN6_IS_ADDR_V4MAPPED(a) \ 00455 (((uint32_t const *) (a))[0] == 0 && \ 00456 ((uint32_t const *) (a))[1] == 0 && \ 00457 ((uint32_t const *) (a))[2] == htonl(0xffff)) 00458 00459 #define SU_IN6_IS_ADDR_V4COMPAT(a) \ 00460 (((uint32_t const *)(a))[0] == 0 && \ 00461 ((uint32_t const *)(a))[1] == 0 && \ 00462 ((uint32_t const *)(a))[2] == 0 && \ 00463 ((uint32_t const *)(a))[3] != htonl(1) && \ 00464 ((uint32_t const *)(a))[3] != htonl(0)) 00465 00466 SOFIAPUBFUN int su_cmp_sockaddr(su_sockaddr_t const *a, 00467 su_sockaddr_t const *b); 00468 SOFIAPUBFUN int su_match_sockaddr(su_sockaddr_t const *a, 00469 su_sockaddr_t const *b); 00470 SOFIAPUBFUN void su_canonize_sockaddr(su_sockaddr_t *su); 00471 00472 #if SU_HAVE_IN6 00473 #define SU_CANONIZE_SOCKADDR(su) \ 00474 ((su)->su_family == AF_INET6 ? su_canonize_sockaddr(su) : (void)0) 00475 #else 00476 #define SU_CANONIZE_SOCKADDR(su) \ 00477 ((void)0) 00478 #endif 00479 00480 SOFIA_END_DECLS 00481 00482 #ifndef SU_ADDRINFO_H 00483 #include <sofia-sip/su_addrinfo.h> 00484 #endif 00485 00486 #endif /* !defined(SU_H) */