KVIrc 5.2.4
Developer APIs
kvi_socket.h
Go to the documentation of this file.
1#ifndef _KVI_SOCKET_H_
2#define _KVI_SOCKET_H_
3//=============================================================================
4//
5// File : kvi_socket.h
6// Creation date : Thu Sep 20 03:50:22 2001 GMT by Szymon Stefanek
7//
8// This file is part of the KVIrc IRC client distribution
9// Copyright (C) 2001-2010 Szymon Stefanek (pragma at kvirc dot net)
10//
11// This program is FREE software. You can redistribute it and/or
12// modify it under the terms of the GNU General Public License
13// as published by the Free Software Foundation; either version 2
14// of the License, or (at your option) any later version.
15//
16// This program is distributed in the HOPE that it will be USEFUL,
17// but WITHOUT ANY WARRANTY; without even the implied warranty of
18// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19// See the GNU General Public License for more details.
20//
21// You should have received a copy of the GNU General Public License
22// along with this program. If not, write to the Free Software Foundation,
23// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
24//
25//=============================================================================
26
27//
28// Socket stuff abstraction layer
29//
30
31#include "kvi_settings.h"
32#include "kvi_sockettype.h" // <--- this includes <winsock2.h> if needed
33
34#include <errno.h>
35
36#include "kvi_inttypes.h"
37
38//#ifndef _KVI_SOCKET_CPP_
41//#endif //!_KVI_SOCKET_CPP_
42
43#if defined(COMPILE_ON_WINDOWS) || (defined(COMPILE_ON_MINGW) && !defined(OS2))
44
45#define KVI_INVALID_SOCKET INVALID_SOCKET
46
47//every decent win version should contain IPPROTO_IPV6
48
49//mingw win32 headers do not have this, mingw-w64-headers do however
50#if defined(COMPILE_ON_MINGW)
51#ifndef IPV6_PROTECTION_LEVEL
52#define IPV6_PROTECTION_LEVEL 23
53#define PROTECTION_LEVEL_UNRESTRICTED 10 /* for peer-to-peer apps */
54#define PROTECTION_LEVEL_DEFAULT 20 /* default level */
55#define PROTECTION_LEVEL_RESTRICTED 30 /* for Intranet apps */
56#endif
57#endif
58
59#define KVI_IPV6_PROTECTION_LEVEL IPV6_PROTECTION_LEVEL
60#define KVI_PROTECTION_LEVEL_RESTRICTED PROTECTION_LEVEL_RESTRICTED
61#define KVI_PROTECTION_LEVEL_DEFAULT PROTECTION_LEVEL_DEFAULT
62#define KVI_PROTECTION_LEVEL_UNRESTRICTED PROTECTION_LEVEL_UNRESTRICTED
63#define KVI_IPPROTO_IPV6 IPPROTO_IPV6
64
65#else
66
67#include <sys/time.h>
68#include <sys/types.h>
69#include <sys/socket.h>
70#include <netinet/tcp.h>
71#include <netinet/in.h>
72#include <fcntl.h>
73#include <unistd.h>
74
75#define KVI_INVALID_SOCKET (-1)
76#endif
77
78#ifndef MSG_NOSIGNAL
79// At least solaris seems to not have it
80#define MSG_NOSIGNAL 0
81#endif
82
83//
84// Constants for kvi_socket_create
85//
86
87#define KVI_SOCKET_PF_INET PF_INET
88#define KVI_SOCKET_PF_INET6 PF_INET6
89#define KVI_SOCKET_PF_UNIX PF_UNIX
90
91#define KVI_SOCKET_TYPE_STREAM SOCK_STREAM
92#define KVI_SOCKET_TYPE_DGRAM SOCK_DGRAM
93
94#define KVI_SOCKET_PROTO_TCP 0
95
96//
97// kvi_socket_create
98// kvi_socket_open
99//
100// Open a socket of the specified protocol family, type and protocol
101// You should always use the KVI_SOCKET_* constants as parameters
102// Returns KVI_INVALID_SOCKET if the socket creation has failed.
103// The returned socket is in blocking mode!
104//
105
106#define kvi_socket_open kvi_socket_create
107
108inline kvi_socket_t kvi_socket_create(int pf, int type, int proto)
109{
110#ifdef COMPILE_ON_MAC
111 /*
112 * Ignore SIGPIPE. Under linux we set MSG_NOSIGNAL on send and recv calls,
113 * but under OSX (and probably other *BSD) we need to set SO_NOSIGPIPE
114 */
115 kvi_socket_t fd = (kvi_socket_t)socket(pf, type, proto);
116 int set = 1;
117 setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, (void *)&set, sizeof(int));
118 return fd;
119#else
120 return (kvi_socket_t)socket(pf, type, proto);
121#endif
122}
123
124//
125// kvi_socket_isValid
126//
127// Check if a socket is valid or not
128//
129
135
137{
138 return (sock != ((kvi_socket_t)(KVI_INVALID_SOCKET)));
139}
140
141//
142// kvi_socket_destroy
143// kvi_socket_close
144//
145// Close a socket...that's all :)
146//
147
148#define kvi_socket_close kvi_socket_destroy
149
151{
152#if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW)
153 closesocket(sock);
154#else
155 close(sock);
156#endif
157}
158
159//
160// kvi_socket_setNonBlocking
161//
162// Sets the socket in nonBlocking mode. Obviously returns false in case of failure
163//
164
166{
167#if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW)
168 unsigned long arg = 1;
169 return (ioctlsocket(sock, FIONBIO, (unsigned long FAR *)&arg) == 0);
170#else
171 return (fcntl(sock, F_SETFL, O_NONBLOCK) == 0);
172#endif
173}
174
175//
176// kvi_socket_bind
177//
178// Standard bind() call on the socket. Returns false in case of failure
179//
180
181inline bool kvi_socket_bind(kvi_socket_t sock, const struct sockaddr * sa, int salen)
182{
183 return (::bind(sock, sa, salen) == 0);
184}
185
186//
187// kvi_socket_connect
188//
189// Starts a connection to the specified remote address
190// returns false if the connection can not be started.
191// You might take a look at kvi_socket_errno() then.
192//
193
194inline bool kvi_socket_connect(kvi_socket_t sock, const struct sockaddr * sa, int salen)
195{
196#if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW)
197 return (WSAConnect(sock, sa, salen, 0, 0, 0, 0) == 0);
198#else
199 return (::connect(sock, sa, salen) == 0);
200#endif
201}
202
204{
205#if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW)
206 return ((err == WSAEINPROGRESS) || (err == WSAEWOULDBLOCK));
207#else
208 return (err == EINPROGRESS);
209#endif
210}
211
212inline bool kvi_socket_recoverableError(int err)
213{
214#if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW)
215 return ((err == WSAEWOULDBLOCK) || (err == EINTR) || (err == EAGAIN));
216#else
217 return ((err == EINTR) || (err == EAGAIN));
218#endif
219}
220
221//
222// kvi_socket_accept
223//
224// Standard accept() call. Returns KVI_INVALID_SOCKET in case of failure
225// You should check kvi_socket_errno() then.
226//
227
228inline kvi_socket_t kvi_socket_accept(kvi_socket_t sock, struct sockaddr * sa, int * salen)
229{
230#if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW)
231 return (kvi_socket_t)::accept(sock, sa, salen);
232#else
233 return (kvi_socket_t)::accept(sock, sa, (socklen_t *)salen);
234#endif
235}
236
237//
238// kvi_socket_listen
239//
240// Standard listen() call. Returns false in case of failure
241// You should check kvi_socket_errno() then.
242//
243
244inline bool kvi_socket_listen(kvi_socket_t sock, int backlog)
245{
246 return (::listen(sock, backlog) == 0);
247}
248
249//
250// kvi_socket_select
251//
252// Standard select() call. This is complex so here is a mini-reminder:
253// nhpo is the number of the highest file descriptor in the sets plus one!
254// Returns the number of sockets with data available (or space available)
255// or something that is less than 0 in case of error. You should check kvi_socket_errno() then.
256//
257
258inline int kvi_socket_select(int nhpo, fd_set * r, fd_set * w, fd_set * e, struct timeval * t)
259{
260 return ::select(nhpo, r, w, e, t);
261}
262
263//
264// kvi_socket_send
265// kvi_socket_write
266//
267// Standard send() call. On UNIX ignores SIGPIPE. Returns the number of bytes sent or
268// -1 in case of failure. You should check kvi_socket_errno() then.
269//
270
271#define kvi_socket_write kvi_socket_send
272
273inline int kvi_socket_send(kvi_socket_t sock, const void * buf, int size)
274{
275 g_uOutgoingTraffic += size;
276#if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW)
277 return ::send(sock, (const char *)buf, size, 0);
278#else
279 return ::send(sock, buf, size, MSG_NOSIGNAL | MSG_DONTWAIT);
280#endif
281}
282
283//
284// kvi_socket_recv
285// kvi_socket_read
286//
287// Standard read() call. On UNIX ignores SIGPIPE. Returns the number of bytes readed or
288// -1 in case of failure. You should check kvi_socket_errno() then.
289//
290
291#define kvi_socket_read kvi_socket_recv
292
293inline int kvi_socket_recv(kvi_socket_t sock, void * buf, int maxlen)
294{
295 int iReceived;
296#if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW)
297 iReceived = ::recv(sock, (char *)buf, maxlen, 0);
298#else
299 iReceived = ::recv(sock, buf, maxlen, MSG_NOSIGNAL);
300#endif
301 g_uIncomingTraffic += iReceived;
302 return iReceived;
303}
304
305//
306// kvi_socket_getsockopt
307//
308// Standard getsockopt() call. Returns false in case of failure.
309// You should check kvi_socket_errno() then.
310//
311
312inline bool kvi_socket_getsockopt(kvi_socket_t sock, int level, int optname, void * optval, int * optlen)
313{
314#if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW)
315 return (::getsockopt(sock, level, optname, (char FAR *)optval, optlen) == 0);
316#else
317 return (::getsockopt(sock, level, optname, optval, (socklen_t *)optlen) == 0);
318#endif
319}
320
321//
322// kvi_socket_setsockopt
323//
324// Standard setsockopt() call. Returns false in case of failure.
325// You should check kvi_socket_errno() then.
326//
327
328inline bool kvi_socket_setsockopt(kvi_socket_t sock, int level, int optname, const void * optval, int optlen)
329{
330#if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW)
331 return (::setsockopt(sock, level, optname, (char FAR *)optval, optlen) == 0);
332#else
333 return (::setsockopt(sock, level, optname, optval, optlen) == 0);
334#endif
335}
336
337//
338// kvi_socket_disableNagle
339//
340// Disables the nagle algorithm (sets TCP_NODELAY)
341//
342
343/*
344 unused for now
345inline bool kvi_socket_disableNagle(kvi_socket_t sock)
346{
347 int opt = 1;
348 return kvi_socket_setsockopt(sock,IPPROTO_TCP,TCP_NODELAY,&opt,sizeof(opt));
349}
350*/
351
352//
353// kvi_socket_getsockname
354//
355// Standard getsockname() call. Returns false in case of failure.
356// You should check kvi_socket_errno() then.
357//
358
359inline bool kvi_socket_getsockname(kvi_socket_t sock, struct sockaddr * addr, int * addrlen)
360{
361#if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW)
362 return (::getsockname(sock, addr, addrlen) == 0);
363#else
364 return (::getsockname(sock, addr, (socklen_t *)addrlen) == 0);
365#endif
366}
367
369{
370#if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW)
371 return WSAGetLastError();
372#else
373 return errno;
374#endif
375}
376
377#endif //_KVI_SOCKET_H_
connect(m_pFtp, SIGNAL(commandFinished(int, bool)), this, SLOT(slotCommandFinished(int, bool)))
#define t
Definition detector.cpp:85
#define e
Definition detector.cpp:70
#define r
Definition detector.cpp:83
#define w
Definition detector.cpp:88
unsigned long long int kvi_u64_t
Definition kvi_inttypes.h:66
This file contains compile time settings.
#define KVILIB_API
Definition kvi_settings.h:124
int kvi_socket_error()
Definition kvi_socket.h:368
bool kvi_socket_bind(kvi_socket_t sock, const struct sockaddr *sa, int salen)
Definition kvi_socket.h:181
void kvi_socket_flushTrafficCounters()
Definition kvi_socket.h:130
bool kvi_socket_connect(kvi_socket_t sock, const struct sockaddr *sa, int salen)
Definition kvi_socket.h:194
bool kvi_socket_recoverableConnectError(int err)
Definition kvi_socket.h:203
int kvi_socket_recv(kvi_socket_t sock, void *buf, int maxlen)
Definition kvi_socket.h:293
bool kvi_socket_recoverableError(int err)
Definition kvi_socket.h:212
KVILIB_API kvi_u64_t g_uOutgoingTraffic
Definition kvi_socket.cpp:30
int kvi_socket_select(int nhpo, fd_set *r, fd_set *w, fd_set *e, struct timeval *t)
Definition kvi_socket.h:258
bool kvi_socket_setNonBlocking(kvi_socket_t sock)
Definition kvi_socket.h:165
bool kvi_socket_setsockopt(kvi_socket_t sock, int level, int optname, const void *optval, int optlen)
Definition kvi_socket.h:328
int kvi_socket_send(kvi_socket_t sock, const void *buf, int size)
Definition kvi_socket.h:273
#define MSG_NOSIGNAL
(defined(COMPILE_ON_WINDOWS) || (defined(COMPILE_ON_MINGW) && !defined(OS2))
Definition kvi_socket.h:80
kvi_socket_t kvi_socket_accept(kvi_socket_t sock, struct sockaddr *sa, int *salen)
Definition kvi_socket.h:228
void kvi_socket_destroy(kvi_socket_t sock)
Definition kvi_socket.h:150
KVILIB_API kvi_u64_t g_uIncomingTraffic
Definition kvi_socket.cpp:31
bool kvi_socket_isValid(kvi_socket_t sock)
Definition kvi_socket.h:136
bool kvi_socket_getsockopt(kvi_socket_t sock, int level, int optname, void *optval, int *optlen)
Definition kvi_socket.h:312
bool kvi_socket_getsockname(kvi_socket_t sock, struct sockaddr *addr, int *addrlen)
Definition kvi_socket.h:359
#define KVI_INVALID_SOCKET
(defined(COMPILE_ON_WINDOWS) || (defined(COMPILE_ON_MINGW) && !defined(OS2))
Definition kvi_socket.h:75
bool kvi_socket_listen(kvi_socket_t sock, int backlog)
Definition kvi_socket.h:244
kvi_socket_t kvi_socket_create(int pf, int type, int proto)
Definition kvi_socket.h:108
int kvi_socket_t
Definition kvi_sockettype.h:40