su 1.12.10
|
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 #define su_family su_sa.sa_family 00167 #else 00168 #define su_len su_array[0] 00169 short su_family; 00170 #endif 00171 #define su_port su_sin.sin_port 00172 #endif 00173 00174 char su_array[32]; 00175 uint16_t su_array16[16]; 00176 uint32_t su_array32[8]; 00177 struct sockaddr su_sa; 00178 struct sockaddr_in su_sin; 00179 #if SU_HAVE_IN6 00180 struct sockaddr_in6 su_sin6; 00181 #endif 00182 #ifdef DOCUMENTATION_ONLY 00183 uint32_t su_scope_id; 00184 #else 00185 #define su_scope_id su_array32[6] 00186 #endif 00187 }; 00188 00189 typedef union su_sockaddr_u su_sockaddr_t; 00190 00191 #if SU_HAVE_BSDSOCK || DOCUMENTATION_ONLY 00192 00202 typedef size_t su_ioveclen_t; 00203 00240 typedef struct su_iovec_s { 00241 void *siv_base; 00242 su_ioveclen_t siv_len; 00243 } su_iovec_t; 00244 00251 #define SU_IOVECLEN_MAX SIZE_MAX 00252 #endif 00253 00254 #if SU_HAVE_WINSOCK 00255 typedef u_long su_ioveclen_t; 00256 00257 /* This is same as WSABUF */ 00258 typedef struct su_iovec_s { 00259 su_ioveclen_t siv_len; 00260 void *siv_base; 00261 } su_iovec_t; 00262 00263 #define SU_IOVECLEN_MAX ULONG_MAX 00264 #endif 00265 00266 /* ---------------------------------------------------------------------- */ 00267 /* Socket compatibility functions */ 00268 00269 SOFIAPUBFUN int su_init(void); 00270 SOFIAPUBFUN void su_deinit(void); 00271 00273 SOFIAPUBFUN su_socket_t su_socket(int af, int sock, int proto); 00275 SOFIAPUBFUN int su_close(su_socket_t s); 00277 SOFIAPUBFUN int su_ioctl(su_socket_t s, int request, ...); 00278 00288 SOFIAPUBFUN int su_is_blocking(int errcode); 00289 00291 SOFIAPUBFUN int su_setblocking(su_socket_t s, int blocking); 00293 SOFIAPUBFUN int su_setreuseaddr(su_socket_t s, int reuse); 00295 SOFIAPUBFUN int su_soerror(su_socket_t s); 00297 SOFIAPUBFUN int su_getsocktype(su_socket_t s); 00298 00300 SOFIAPUBFUN issize_t su_getmsgsize(su_socket_t s); 00301 00303 SOFIAPUBFUN 00304 issize_t su_vsend(su_socket_t, su_iovec_t const iov[], isize_t len, int flags, 00305 su_sockaddr_t const *su, socklen_t sulen); 00307 SOFIAPUBFUN 00308 issize_t su_vrecv(su_socket_t, su_iovec_t iov[], isize_t len, int flags, 00309 su_sockaddr_t *su, socklen_t *sulen); 00311 SOFIAPUBFUN int su_getlocalip(su_sockaddr_t *sin); 00312 00313 #if SU_HAVE_BSDSOCK 00314 #define su_ioctl ioctl 00315 /* 00316 * Note: before 1.12.2, there was su_isblocking() which did not take argument 00317 * and which was missing from WINSOCK 00318 */ 00319 #define su_is_blocking(e) \ 00320 ((e) == EINPROGRESS || (e) == EAGAIN || (e) == EWOULDBLOCK) 00321 #endif 00322 00323 #if SU_HAVE_WINSOCK 00324 SOFIAPUBFUN int su_inet_pton(int af, char const *src, void *dst); 00325 SOFIAPUBFUN const char *su_inet_ntop(int af, void const *src, 00326 char *dst, size_t size); 00327 SOFIAPUBFUN ssize_t 00328 su_send(su_socket_t s, void *buffer, size_t length, int flags), 00329 su_sendto(su_socket_t s, void *buffer, size_t length, int flags, 00330 su_sockaddr_t const *to, socklen_t tolen), 00331 su_recv(su_socket_t s, void *buffer, size_t length, int flags), 00332 su_recvfrom(su_socket_t s, void *buffer, size_t length, int flags, 00333 su_sockaddr_t *from, socklen_t *fromlen); 00334 00335 static __inline 00336 uint16_t su_ntohs(uint16_t s) 00337 { 00338 return (uint16_t)(((s & 255) << 8) | ((s & 0xff00) >> 8)); 00339 } 00340 00341 static __inline 00342 uint32_t su_ntohl(uint32_t l) 00343 { 00344 return ((l & 0xff) << 24) | ((l & 0xff00) << 8) 00345 | ((l & 0xff0000) >> 8) | ((l & 0xff000000U) >> 24); 00346 } 00347 00348 #define ntohs su_ntohs 00349 #define htons su_ntohs 00350 #define ntohl su_ntohl 00351 #define htonl su_ntohl 00352 00353 #else 00354 #define su_inet_pton inet_pton 00355 #define su_inet_ntop inet_ntop 00356 #define su_send(s,b,l,f) send((s),(b),(l),(f)) 00357 #define su_sendto(s,b,l,f,a,L) sendto((s),(b),(l),(f),(void const*)(a),(L)) 00358 #define su_recv(s,b,l,f) recv((s),(b),(l),(f)) 00359 #define su_recvfrom(s,b,l,f,a,L) recvfrom((s),(b),(l),(f),(void *)(a),(L)) 00360 #endif 00361 00362 /* ---------------------------------------------------------------------- */ 00363 /* Other compatibility stuff */ 00364 00365 #if SU_HAVE_WINSOCK 00366 #define getuid() (0x505) 00367 #endif 00368 00369 #ifndef IPPROTO_SCTP 00370 #define IPPROTO_SCTP (132) 00371 #endif 00372 00373 /* ---------------------------------------------------------------------- */ 00374 /* Address manipulation macros */ 00375 00381 #if SU_HAVE_IN6 00382 #define SU_ADDR(su) \ 00383 ((su)->su_family == AF_INET ? (void *)&(su)->su_sin.sin_addr : \ 00384 ((su)->su_family == AF_INET6 ? (void *)&(su)->su_sin6.sin6_addr : \ 00385 (void *)&(su)->su_sa.sa_data)) 00386 #else 00387 #define SU_ADDR(su) \ 00388 ((su)->su_family == AF_INET ? (void *)&(su)->su_sin.sin_addr : \ 00389 (void *)&(su)->su_sa.sa_data) 00390 #endif 00391 00397 #if SU_HAVE_IN6 00398 #define SU_ADDRLEN(su) \ 00399 ((su)->su_family == AF_INET \ 00400 ? (socklen_t)sizeof((su)->su_sin.sin_addr) : \ 00401 ((su)->su_family == AF_INET6 \ 00402 ? (socklen_t)sizeof((su)->su_sin6.sin6_addr) \ 00403 : (socklen_t)sizeof((su)->su_sa.sa_data))) 00404 #else 00405 #define SU_ADDRLEN(su) \ 00406 ((su)->su_family == AF_INET \ 00407 ? (socklen_t)sizeof((su)->su_sin.sin_addr) \ 00408 : (socklen_t)sizeof((su)->su_sa.sa_data)) 00409 #endif 00410 00412 #if SU_HAVE_IN6 00413 #define SU_HAS_INADDR_ANY(su) \ 00414 ((su)->su_family == AF_INET \ 00415 ? ((su)->su_sin.sin_addr.s_addr == INADDR_ANY) \ 00416 : ((su)->su_family == AF_INET6 \ 00417 ? (memcmp(&(su)->su_sin6.sin6_addr, su_in6addr_any(), \ 00418 sizeof(*su_in6addr_any())) == 0) : 0)) 00419 #else 00420 #define SU_HAS_INADDR_ANY(su) \ 00421 ((su)->su_family == AF_INET \ 00422 ? ((su)->su_sin.sin_addr.s_addr == INADDR_ANY) : 0) 00423 #endif 00424 00425 #define SU_SOCKADDR_INADDR_ANY(su) SU_HAS_INADDR_ANY(su) 00426 00428 #if SU_HAVE_IN6 00429 #define SU_SOCKADDR_SIZE(su) \ 00430 ((socklen_t)((su)->su_family == AF_INET ? sizeof((su)->su_sin) \ 00431 : ((su)->su_family == AF_INET6 ? sizeof((su)->su_sin6) \ 00432 : sizeof(*su)))) 00433 #else 00434 #define SU_SOCKADDR_SIZE(su) \ 00435 ((socklen_t)((su)->su_family == AF_INET ? sizeof((su)->su_sin) \ 00436 : sizeof(*su))) 00437 #endif 00438 #define su_sockaddr_size SU_SOCKADDR_SIZE 00439 00440 #if SU_HAVE_IN6 00441 #if SU_HAVE_BSDSOCK 00442 #define su_in6addr_any() (&in6addr_any) 00443 #define su_in6addr_loopback() (&in6addr_loopback) 00444 #define SU_IN6ADDR_ANY_INIT IN6ADDR_ANY_INIT 00445 #define SU_IN6ADDR_LOOPBACK_INIT IN6ADDR_LOOPBACK_INIT 00446 #endif 00447 #if SU_HAVE_WINSOCK || DOCUMENTATION_ONLY 00448 SOFIAPUBVAR const struct in_addr6 *su_in6addr_any(void); 00449 SOFIAPUBVAR const struct in_addr6 *su_in6addr_loopback(void); 00450 #define SU_IN6ADDR_ANY_INIT { 0 } 00451 #define SU_IN6ADDR_LOOPBACK_INIT { 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,1 } 00452 #endif 00453 #endif /* SU_HAVE_IN6 */ 00454 00455 #define SU_IN6_IS_ADDR_V4MAPPED(a) \ 00456 (((uint32_t const *) (a))[0] == 0 && \ 00457 ((uint32_t const *) (a))[1] == 0 && \ 00458 ((uint32_t const *) (a))[2] == htonl(0xffff)) 00459 00460 #define SU_IN6_IS_ADDR_V4COMPAT(a) \ 00461 (((uint32_t const *)(a))[0] == 0 && \ 00462 ((uint32_t const *)(a))[1] == 0 && \ 00463 ((uint32_t const *)(a))[2] == 0 && \ 00464 ((uint32_t const *)(a))[3] != htonl(1) && \ 00465 ((uint32_t const *)(a))[3] != htonl(0)) 00466 00467 SOFIAPUBFUN int su_cmp_sockaddr(su_sockaddr_t const *a, 00468 su_sockaddr_t const *b); 00469 SOFIAPUBFUN int su_match_sockaddr(su_sockaddr_t const *a, 00470 su_sockaddr_t const *b); 00471 SOFIAPUBFUN void su_canonize_sockaddr(su_sockaddr_t *su); 00472 00473 #if SU_HAVE_IN6 00474 #define SU_CANONIZE_SOCKADDR(su) \ 00475 ((su)->su_family == AF_INET6 ? su_canonize_sockaddr(su) : (void)0) 00476 #else 00477 #define SU_CANONIZE_SOCKADDR(su) \ 00478 ((void)0) 00479 #endif 00480 00481 SOFIA_END_DECLS 00482 00483 #ifndef SU_ADDRINFO_H 00484 #include <sofia-sip/su_addrinfo.h> 00485 #endif 00486 00487 #endif /* !defined(SU_H) */