/src/resiprocate/rutil/Socket.hxx
Line | Count | Source |
1 | | #if !defined(RESIP_SOCKET_HXX) |
2 | | #define RESIP_SOCKET_HXX |
3 | | |
4 | | #include "rutil/ResipAssert.h" |
5 | | #include <errno.h> |
6 | | #include <algorithm> |
7 | | |
8 | | #ifdef WIN32 |
9 | | #include <winsock2.h> |
10 | | #include <stdlib.h> |
11 | | #include <io.h> |
12 | | #include <WS2TCPIP.H> |
13 | | #endif |
14 | | |
15 | | #include "compat.hxx" |
16 | | #include "rutil/TransportType.hxx" |
17 | | |
18 | | /** |
19 | | @file |
20 | | @brief Handles cross-platform sockets compatibility. |
21 | | */ |
22 | | |
23 | | #ifdef WIN32 |
24 | | |
25 | | /** With VS 2010 Berkeley errno constants have been redefined and are now different than WSAGetLastError() WSA prefixed constants. |
26 | | @see http://msdn.microsoft.com/en-us/library/ms737828(VS.85).aspx, https://connect.microsoft.com/VisualStudio/feedback/details/509380/errno-h-socket-return-codes-now-inconsistent-with-wsagetlasterror?wa=wsignin1.0 |
27 | | @see <winsock2.h> |
28 | | The recommended fix is to use WSAGetLastError() and with the WSAXXX constants. One way to do this would be to create RESIP_XXX socket constants that would correclty use WSAXXX constants |
29 | | on windows without using the Berkeley style constants. For now just re-assign the Berkeley style constants as WSA constants. |
30 | | */ |
31 | | #if defined(_MSC_VER) && (_MSC_VER >= 1600) |
32 | | #pragma warning (push) |
33 | | #pragma warning (disable: 4005 ) |
34 | | #endif |
35 | | typedef int socklen_t; |
36 | | |
37 | | //this list taken from <winsock2.h>, see #if 0 removed block. |
38 | | #define EWOULDBLOCK WSAEWOULDBLOCK |
39 | | #define EINPROGRESS WSAEINPROGRESS |
40 | | #define EALREADY WSAEALREADY |
41 | | #define ENOTSOCK WSAENOTSOCK |
42 | | #define EDESTADDRREQ WSAEDESTADDRREQ |
43 | | #define EMSGSIZE WSAEMSGSIZE |
44 | | #define EPROTOTYPE WSAEPROTOTYPE |
45 | | #define ENOPROTOOPT WSAENOPROTOOPT |
46 | | #define EPROTONOSUPPORT WSAEPROTONOSUPPORT |
47 | | #define ESOCKTNOSUPPORT WSAESOCKTNOSUPPORT |
48 | | #define EOPNOTSUPP WSAEOPNOTSUPP |
49 | | #define EPFNOSUPPORT WSAEPFNOSUPPORT |
50 | | #define EAFNOSUPPORT WSAEAFNOSUPPORT |
51 | | #define EADDRINUSE WSAEADDRINUSE |
52 | | #define EADDRNOTAVAIL WSAEADDRNOTAVAIL |
53 | | #define ENETDOWN WSAENETDOWN |
54 | | #define ENETUNREACH WSAENETUNREACH |
55 | | #define ENETRESET WSAENETRESET |
56 | | #define ECONNABORTED WSAECONNABORTED |
57 | | #define ECONNRESET WSAECONNRESET |
58 | | #define ENOBUFS WSAENOBUFS |
59 | | #define EISCONN WSAEISCONN |
60 | | #define ENOTCONN WSAENOTCONN |
61 | | #define ESHUTDOWN WSAESHUTDOWN |
62 | | #define ETOOMANYREFS WSAETOOMANYREFS |
63 | | #define ETIMEDOUT WSAETIMEDOUT |
64 | | #define ECONNREFUSED WSAECONNREFUSED |
65 | | #define ELOOP WSAELOOP |
66 | | //#define ENAMETOOLONG WSAENAMETOOLONG |
67 | | #define EHOSTDOWN WSAEHOSTDOWN |
68 | | #define EHOSTUNREACH WSAEHOSTUNREACH |
69 | | //#define ENOTEMPTY WSAENOTEMPTY |
70 | | #define EPROCLIM WSAEPROCLIM |
71 | | #define EUSERS WSAEUSERS |
72 | | #define EDQUOT WSAEDQUOT |
73 | | #define ESTALE WSAESTALE |
74 | | #define EREMOTE WSAEREMOTE |
75 | | |
76 | | #if defined(_MSC_VER) && (_MSC_VER >= 1600) |
77 | | #pragma warning (pop) |
78 | | #endif |
79 | | |
80 | | #else |
81 | | |
82 | 0 | #define WSANOTINITIALISED EPROTONOSUPPORT |
83 | | |
84 | | #endif |
85 | | |
86 | | namespace resip |
87 | | { |
88 | | |
89 | | /// set up network - does nothing in unix but needed for windows |
90 | | void |
91 | | initNetwork(); |
92 | | |
93 | | #ifndef WIN32 |
94 | | typedef int Socket; // Un*x fds are signed |
95 | | #define INVALID_SOCKET (-1) |
96 | | #define SOCKET_ERROR (-1) |
97 | 0 | inline int getErrno() { return errno; } |
98 | | #else |
99 | | typedef SOCKET Socket; // Windows defines as *unsigned* something |
100 | | // INVALID_SOCKET is defined by Windows as ~0 (since Windows socket unsigned) |
101 | | // SOCKET_ERROR is defined by Windows as -1 (most func retvals are signed) |
102 | | inline int getErrno() { return WSAGetLastError(); } |
103 | | #endif |
104 | | |
105 | | //c function pointer because of ares |
106 | | extern "C" { |
107 | | typedef void(*AfterSocketCreationFuncPtr)(Socket s, int transportType, const char* file, int line); |
108 | | } |
109 | | |
110 | | bool makeSocketNonBlocking(Socket fd); |
111 | | bool makeSocketBlocking(Socket fd); |
112 | | bool configureConnectedSocket(Socket fd); |
113 | | int closeSocket( Socket fd ); |
114 | | int getSocketError(Socket fd); // getsockopt(SOCK_SOCKET,SO_ERROR) |
115 | | int increaseLimitFds(unsigned int targetFds); |
116 | | int setSocketRcvBufLen(Socket fd, int buflen); // setsockopt(SO_RCVBUF) |
117 | | |
118 | | |
119 | | /** |
120 | | @brief Object-oriented wrapper for your platform's file-descriptor set. |
121 | | */ |
122 | | class FdSet |
123 | | { |
124 | | public: |
125 | | FdSet() : size(0), numReady(0) |
126 | 0 | { |
127 | 0 | FD_ZERO(&read); |
128 | 0 | FD_ZERO(&write); |
129 | 0 | FD_ZERO(&except); |
130 | 0 | } |
131 | | |
132 | | int select() |
133 | 0 | { |
134 | 0 | return numReady = ::select(size, &read, &write, &except, NULL); |
135 | 0 | } |
136 | | |
137 | | int select(struct timeval& tv) |
138 | 0 | { |
139 | 0 | return numReady = ::select(size, &read, &write, &except, &tv); |
140 | 0 | } |
141 | | |
142 | | int selectMilliSeconds(unsigned long ms) |
143 | 0 | { |
144 | 0 | struct timeval tv; |
145 | 0 | tv.tv_sec = (ms/1000); |
146 | 0 | tv.tv_usec = (ms%1000)*1000; |
147 | 0 | return select(tv); |
148 | 0 | } |
149 | | |
150 | | bool readyToRead(Socket fd) |
151 | 0 | { |
152 | 0 | return (FD_ISSET(fd, &read) != 0); |
153 | 0 | } |
154 | | |
155 | | bool readyToWrite(Socket fd) |
156 | 0 | { |
157 | 0 | return (FD_ISSET(fd, &write) != 0); |
158 | 0 | } |
159 | | |
160 | | bool hasException(Socket fd) |
161 | 0 | { |
162 | 0 | return (FD_ISSET(fd,&except) != 0); |
163 | 0 | } |
164 | | |
165 | | void setRead(Socket fd) |
166 | 0 | { |
167 | 0 | resip_assert( FD_SETSIZE >= 8 ); |
168 | 0 | #ifndef WIN32 // windows fd are not int's and don't start at 0 - this won't work in windows |
169 | 0 | resip_assert( fd < (int)FD_SETSIZE ); // redefineing FD_SETSIZE will not work |
170 | 0 | #else |
171 | 0 | resip_assert(read.fd_count < FD_SETSIZE); // Ensure there is room to add new FD |
172 | 0 | #endif |
173 | 0 | FD_SET(fd, &read); |
174 | 0 | size = ( int(fd+1) > size) ? int(fd+1) : size; |
175 | 0 | } |
176 | | |
177 | | void setWrite(Socket fd) |
178 | 0 | { |
179 | 0 | #ifndef WIN32 // windows fd are not int's and don't start at 0 - this won't work in windows |
180 | 0 | resip_assert( fd < (int)FD_SETSIZE ); // redefinitn FD_SETSIZE will not work |
181 | 0 | #else |
182 | 0 | resip_assert(write.fd_count < FD_SETSIZE); // Ensure there is room to add new FD |
183 | 0 | #endif |
184 | 0 | FD_SET(fd, &write); |
185 | 0 | size = ( int(fd+1) > size) ? int(fd+1) : size; |
186 | 0 | } |
187 | | |
188 | | void setExcept(Socket fd) |
189 | 0 | { |
190 | 0 | #ifndef WIN32 // windows fd are not int's and don't start at 0 - this won't work in windows |
191 | 0 | resip_assert( fd < (int)FD_SETSIZE ); // redefinitn FD_SETSIZE will not work |
192 | 0 | #else |
193 | 0 | resip_assert(except.fd_count < FD_SETSIZE); // Ensure there is room to add new FD |
194 | 0 | #endif |
195 | 0 | FD_SET(fd,&except); |
196 | 0 | size = ( int(fd+1) > size) ? int(fd+1) : size; |
197 | 0 | } |
198 | | |
199 | | |
200 | | void clear(Socket fd) |
201 | 0 | { |
202 | 0 | FD_CLR(fd, &read); |
203 | 0 | FD_CLR(fd, &write); |
204 | 0 | FD_CLR(fd, &except); |
205 | 0 | } |
206 | | |
207 | | void reset() |
208 | 0 | { |
209 | 0 | size = 0; |
210 | 0 | numReady = 0; |
211 | 0 | FD_ZERO(&read); |
212 | 0 | FD_ZERO(&write); |
213 | 0 | FD_ZERO(&except); |
214 | 0 | } |
215 | | |
216 | | // Make this stuff public for async dns/ares to use |
217 | | fd_set read; |
218 | | fd_set write; |
219 | | fd_set except; |
220 | | int size; |
221 | | int numReady; // set after each select call |
222 | | }; |
223 | | |
224 | | |
225 | | } |
226 | | |
227 | | #endif |
228 | | |
229 | | /* ==================================================================== |
230 | | * The Vovida Software License, Version 1.0 |
231 | | * |
232 | | * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. |
233 | | * |
234 | | * Redistribution and use in source and binary forms, with or without |
235 | | * modification, are permitted provided that the following conditions |
236 | | * are met: |
237 | | * |
238 | | * 1. Redistributions of source code must retain the above copyright |
239 | | * notice, this list of conditions and the following disclaimer. |
240 | | * |
241 | | * 2. Redistributions in binary form must reproduce the above copyright |
242 | | * notice, this list of conditions and the following disclaimer in |
243 | | * the documentation and/or other materials provided with the |
244 | | * distribution. |
245 | | * |
246 | | * 3. The names "VOCAL", "Vovida Open Communication Application Library", |
247 | | * and "Vovida Open Communication Application Library (VOCAL)" must |
248 | | * not be used to endorse or promote products derived from this |
249 | | * software without prior written permission. For written |
250 | | * permission, please contact vocal@vovida.org. |
251 | | * |
252 | | * 4. Products derived from this software may not be called "VOCAL", nor |
253 | | * may "VOCAL" appear in their name, without prior written |
254 | | * permission of Vovida Networks, Inc. |
255 | | * |
256 | | * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED |
257 | | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
258 | | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND |
259 | | * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA |
260 | | * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES |
261 | | * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, |
262 | | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
263 | | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
264 | | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
265 | | * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
266 | | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE |
267 | | * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH |
268 | | * DAMAGE. |
269 | | * |
270 | | * ==================================================================== |
271 | | * |
272 | | * This software consists of voluntary contributions made by Vovida |
273 | | * Networks, Inc. and many individuals on behalf of Vovida Networks, |
274 | | * Inc. For more information on Vovida Networks, Inc., please see |
275 | | * <http://www.vovida.org/>. |
276 | | * |
277 | | * vi: set shiftwidth=3 expandtab: |
278 | | */ |