1 | /** \file Socket.cpp |
---|
2 | ** \date 2004-02-13 |
---|
3 | ** \author grymse@alhem.net |
---|
4 | **/ |
---|
5 | /* |
---|
6 | Copyright (C) 2004-2007 Anders Hedstrom |
---|
7 | |
---|
8 | This library is made available under the terms of the GNU GPL. |
---|
9 | |
---|
10 | If you would like to use this library in a closed-source application, |
---|
11 | a separate license agreement is available. For information about |
---|
12 | the closed-source license agreement for the C++ sockets library, |
---|
13 | please visit http://www.alhem.net/Sockets/license.html and/or |
---|
14 | email license@alhem.net. |
---|
15 | |
---|
16 | This program is free software; you can redistribute it and/or |
---|
17 | modify it under the terms of the GNU General Public License |
---|
18 | as published by the Free Software Foundation; either version 2 |
---|
19 | of the License, or (at your option) any later version. |
---|
20 | |
---|
21 | This program is distributed in the hope that it will be useful, |
---|
22 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
23 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
24 | GNU General Public License for more details. |
---|
25 | |
---|
26 | You should have received a copy of the GNU General Public License |
---|
27 | along with this program; if not, write to the Free Software |
---|
28 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
---|
29 | */ |
---|
30 | #include "Socket.h" |
---|
31 | #ifdef _WIN32 |
---|
32 | #ifdef _MSC_VER |
---|
33 | #pragma warning(disable:4786) |
---|
34 | #endif |
---|
35 | #include <stdlib.h> |
---|
36 | #else |
---|
37 | #include <errno.h> |
---|
38 | #include <netdb.h> |
---|
39 | #endif |
---|
40 | #include <ctype.h> |
---|
41 | #include <fcntl.h> |
---|
42 | |
---|
43 | #include "ISocketHandler.h" |
---|
44 | #include "Utility.h" |
---|
45 | |
---|
46 | #include "SocketAddress.h" |
---|
47 | #include "SocketHandler.h" |
---|
48 | #ifdef ENABLE_EXCEPTIONS |
---|
49 | #include "Exception.h" |
---|
50 | #endif |
---|
51 | #include "Ipv4Address.h" |
---|
52 | |
---|
53 | //#ifdef _DEBUG |
---|
54 | //#define DEB(x) x; fflush(stderr); |
---|
55 | //#else |
---|
56 | #define DEB(x) |
---|
57 | //#endif |
---|
58 | |
---|
59 | #ifdef SOCKETS_NAMESPACE |
---|
60 | namespace SOCKETS_NAMESPACE { |
---|
61 | #endif |
---|
62 | |
---|
63 | |
---|
64 | // statics |
---|
65 | #ifdef _WIN32 |
---|
66 | WSAInitializer Socket::m_winsock_init; |
---|
67 | #endif |
---|
68 | |
---|
69 | |
---|
70 | Socket::Socket(ISocketHandler& h) |
---|
71 | //:m_flags(0) |
---|
72 | :m_handler(h) |
---|
73 | ,m_socket( INVALID_SOCKET ) |
---|
74 | ,m_bDel(false) |
---|
75 | ,m_bClose(false) |
---|
76 | ,m_tCreate(time(NULL)) |
---|
77 | ,m_parent(NULL) |
---|
78 | ,m_b_disable_read(false) |
---|
79 | ,m_connected(false) |
---|
80 | ,m_b_erased_by_handler(false) |
---|
81 | ,m_tClose(0) |
---|
82 | ,m_client_remote_address(NULL) |
---|
83 | ,m_remote_address(NULL) |
---|
84 | ,m_traffic_monitor(NULL) |
---|
85 | ,m_bLost(false) |
---|
86 | #ifdef HAVE_OPENSSL |
---|
87 | ,m_b_enable_ssl(false) |
---|
88 | ,m_b_ssl(false) |
---|
89 | ,m_b_ssl_server(false) |
---|
90 | #endif |
---|
91 | #ifdef ENABLE_IPV6 |
---|
92 | ,m_ipv6(false) |
---|
93 | #endif |
---|
94 | #ifdef ENABLE_POOL |
---|
95 | ,m_socket_type(0) |
---|
96 | ,m_bClient(false) |
---|
97 | ,m_bRetain(false) |
---|
98 | #endif |
---|
99 | #ifdef ENABLE_SOCKS4 |
---|
100 | ,m_bSocks4(false) |
---|
101 | ,m_socks4_host(h.GetSocks4Host()) |
---|
102 | ,m_socks4_port(h.GetSocks4Port()) |
---|
103 | ,m_socks4_userid(h.GetSocks4Userid()) |
---|
104 | #endif |
---|
105 | #ifdef ENABLE_DETACH |
---|
106 | ,m_detach(false) |
---|
107 | ,m_detached(false) |
---|
108 | ,m_pThread(NULL) |
---|
109 | ,m_slave_handler(NULL) |
---|
110 | #endif |
---|
111 | { |
---|
112 | } |
---|
113 | |
---|
114 | |
---|
115 | Socket::~Socket() |
---|
116 | { |
---|
117 | Handler().Remove(this); |
---|
118 | if (m_socket != INVALID_SOCKET |
---|
119 | #ifdef ENABLE_POOL |
---|
120 | && !m_bRetain |
---|
121 | #endif |
---|
122 | ) |
---|
123 | { |
---|
124 | Close(); |
---|
125 | } |
---|
126 | } |
---|
127 | |
---|
128 | |
---|
129 | void Socket::Init() |
---|
130 | { |
---|
131 | } |
---|
132 | |
---|
133 | |
---|
134 | void Socket::OnRead() |
---|
135 | { |
---|
136 | } |
---|
137 | |
---|
138 | |
---|
139 | void Socket::OnWrite() |
---|
140 | { |
---|
141 | } |
---|
142 | |
---|
143 | |
---|
144 | void Socket::OnException() |
---|
145 | { |
---|
146 | // %! exception doesn't always mean something bad happened, this code should be reworked |
---|
147 | // errno valid here? |
---|
148 | int err = SoError(); |
---|
149 | Handler().LogError(this, "exception on select", err, StrError(err), LOG_LEVEL_FATAL); |
---|
150 | SetCloseAndDelete(); |
---|
151 | } |
---|
152 | |
---|
153 | |
---|
154 | void Socket::OnDelete() |
---|
155 | { |
---|
156 | } |
---|
157 | |
---|
158 | |
---|
159 | void Socket::OnConnect() |
---|
160 | { |
---|
161 | } |
---|
162 | |
---|
163 | |
---|
164 | void Socket::OnAccept() |
---|
165 | { |
---|
166 | } |
---|
167 | |
---|
168 | |
---|
169 | int Socket::Close() |
---|
170 | { |
---|
171 | if (m_socket == INVALID_SOCKET) // this could happen |
---|
172 | { |
---|
173 | Handler().LogError(this, "Socket::Close", 0, "file descriptor invalid", LOG_LEVEL_WARNING); |
---|
174 | return 0; |
---|
175 | } |
---|
176 | int n; |
---|
177 | if ((n = closesocket(m_socket)) == -1) |
---|
178 | { |
---|
179 | // failed... |
---|
180 | Handler().LogError(this, "close", Errno, StrError(Errno), LOG_LEVEL_ERROR); |
---|
181 | } |
---|
182 | Handler().Set(m_socket, false, false, false); // remove from fd_set's |
---|
183 | Handler().AddList(m_socket, LIST_CALLONCONNECT, false); |
---|
184 | #ifdef ENABLE_DETACH |
---|
185 | Handler().AddList(m_socket, LIST_DETACH, false); |
---|
186 | #endif |
---|
187 | Handler().AddList(m_socket, LIST_TIMEOUT, false); |
---|
188 | Handler().AddList(m_socket, LIST_RETRY, false); |
---|
189 | Handler().AddList(m_socket, LIST_CLOSE, false); |
---|
190 | m_socket = INVALID_SOCKET; |
---|
191 | return n; |
---|
192 | } |
---|
193 | |
---|
194 | |
---|
195 | SOCKET Socket::CreateSocket(int af,int type, const std::string& protocol) |
---|
196 | { |
---|
197 | struct protoent *p = NULL; |
---|
198 | SOCKET s; |
---|
199 | |
---|
200 | #ifdef ENABLE_POOL |
---|
201 | m_socket_type = type; |
---|
202 | m_socket_protocol = protocol; |
---|
203 | #endif |
---|
204 | if (!protocol.empty()) |
---|
205 | { |
---|
206 | p = getprotobyname( protocol.c_str() ); |
---|
207 | if (!p) |
---|
208 | { |
---|
209 | Handler().LogError(this, "getprotobyname", Errno, StrError(Errno), LOG_LEVEL_FATAL); |
---|
210 | SetCloseAndDelete(); |
---|
211 | #ifdef ENABLE_EXCEPTIONS |
---|
212 | throw Exception(std::string("getprotobyname() failed: ") + StrError(Errno)); |
---|
213 | #endif |
---|
214 | return INVALID_SOCKET; |
---|
215 | } |
---|
216 | } |
---|
217 | int protno = p ? p -> p_proto : 0; |
---|
218 | |
---|
219 | s = socket(af, type, protno); |
---|
220 | if (s == INVALID_SOCKET) |
---|
221 | { |
---|
222 | Handler().LogError(this, "socket", Errno, StrError(Errno), LOG_LEVEL_FATAL); |
---|
223 | SetCloseAndDelete(); |
---|
224 | #ifdef ENABLE_EXCEPTIONS |
---|
225 | throw Exception(std::string("socket() failed: ") + StrError(Errno)); |
---|
226 | #endif |
---|
227 | return INVALID_SOCKET; |
---|
228 | } |
---|
229 | Attach(s); |
---|
230 | OnOptions(af, type, protno, s); |
---|
231 | Attach(INVALID_SOCKET); |
---|
232 | return s; |
---|
233 | } |
---|
234 | |
---|
235 | |
---|
236 | void Socket::Attach(SOCKET s) |
---|
237 | { |
---|
238 | m_socket = s; |
---|
239 | } |
---|
240 | |
---|
241 | |
---|
242 | SOCKET Socket::GetSocket() |
---|
243 | { |
---|
244 | return m_socket; |
---|
245 | } |
---|
246 | |
---|
247 | |
---|
248 | void Socket::SetDeleteByHandler(bool x) |
---|
249 | { |
---|
250 | m_bDel = x; |
---|
251 | } |
---|
252 | |
---|
253 | |
---|
254 | bool Socket::DeleteByHandler() |
---|
255 | { |
---|
256 | return m_bDel; |
---|
257 | } |
---|
258 | |
---|
259 | |
---|
260 | void Socket::SetCloseAndDelete(bool x) |
---|
261 | { |
---|
262 | if (x != m_bClose) |
---|
263 | { |
---|
264 | Handler().AddList(m_socket, LIST_CLOSE, x); |
---|
265 | m_bClose = x; |
---|
266 | if (x) |
---|
267 | { |
---|
268 | m_tClose = time(NULL); |
---|
269 | } |
---|
270 | } |
---|
271 | } |
---|
272 | |
---|
273 | |
---|
274 | bool Socket::CloseAndDelete() |
---|
275 | { |
---|
276 | return m_bClose; |
---|
277 | } |
---|
278 | |
---|
279 | |
---|
280 | void Socket::SetRemoteAddress(SocketAddress& ad) //struct sockaddr* sa, socklen_t l) |
---|
281 | { |
---|
282 | m_remote_address = ad.GetCopy(); |
---|
283 | } |
---|
284 | |
---|
285 | |
---|
286 | std::auto_ptr<SocketAddress> Socket::GetRemoteSocketAddress() |
---|
287 | { |
---|
288 | return m_remote_address -> GetCopy(); |
---|
289 | } |
---|
290 | |
---|
291 | |
---|
292 | ISocketHandler& Socket::Handler() const |
---|
293 | { |
---|
294 | #ifdef ENABLE_DETACH |
---|
295 | if (IsDetached()) |
---|
296 | return *m_slave_handler; |
---|
297 | #endif |
---|
298 | return m_handler; |
---|
299 | } |
---|
300 | |
---|
301 | |
---|
302 | ISocketHandler& Socket::MasterHandler() const |
---|
303 | { |
---|
304 | return m_handler; |
---|
305 | } |
---|
306 | |
---|
307 | |
---|
308 | ipaddr_t Socket::GetRemoteIP4() |
---|
309 | { |
---|
310 | ipaddr_t l = 0; |
---|
311 | #ifdef ENABLE_IPV6 |
---|
312 | if (m_ipv6) |
---|
313 | { |
---|
314 | Handler().LogError(this, "GetRemoteIP4", 0, "get ipv4 address for ipv6 socket", LOG_LEVEL_WARNING); |
---|
315 | } |
---|
316 | #endif |
---|
317 | if (m_remote_address.get() != NULL) |
---|
318 | { |
---|
319 | struct sockaddr *p = *m_remote_address; |
---|
320 | struct sockaddr_in *sa = (struct sockaddr_in *)p; |
---|
321 | memcpy(&l, &sa -> sin_addr, sizeof(struct in_addr)); |
---|
322 | } |
---|
323 | return l; |
---|
324 | } |
---|
325 | |
---|
326 | |
---|
327 | #ifdef ENABLE_IPV6 |
---|
328 | #ifdef IPPROTO_IPV6 |
---|
329 | struct in6_addr Socket::GetRemoteIP6() |
---|
330 | { |
---|
331 | if (!m_ipv6) |
---|
332 | { |
---|
333 | Handler().LogError(this, "GetRemoteIP6", 0, "get ipv6 address for ipv4 socket", LOG_LEVEL_WARNING); |
---|
334 | } |
---|
335 | struct sockaddr_in6 fail; |
---|
336 | if (m_remote_address.get() != NULL) |
---|
337 | { |
---|
338 | struct sockaddr *p = *m_remote_address; |
---|
339 | memcpy(&fail, p, sizeof(struct sockaddr_in6)); |
---|
340 | } |
---|
341 | else |
---|
342 | { |
---|
343 | memset(&fail, 0, sizeof(struct sockaddr_in6)); |
---|
344 | } |
---|
345 | return fail.sin6_addr; |
---|
346 | } |
---|
347 | #endif |
---|
348 | #endif |
---|
349 | |
---|
350 | |
---|
351 | port_t Socket::GetRemotePort() |
---|
352 | { |
---|
353 | if (!m_remote_address.get()) |
---|
354 | { |
---|
355 | return 0; |
---|
356 | } |
---|
357 | return m_remote_address -> GetPort(); |
---|
358 | } |
---|
359 | |
---|
360 | |
---|
361 | std::string Socket::GetRemoteAddress() |
---|
362 | { |
---|
363 | if (!m_remote_address.get()) |
---|
364 | { |
---|
365 | return ""; |
---|
366 | } |
---|
367 | return m_remote_address -> Convert(false); |
---|
368 | } |
---|
369 | |
---|
370 | |
---|
371 | std::string Socket::GetRemoteHostname() |
---|
372 | { |
---|
373 | if (!m_remote_address.get()) |
---|
374 | { |
---|
375 | return ""; |
---|
376 | } |
---|
377 | return m_remote_address -> Reverse(); |
---|
378 | } |
---|
379 | |
---|
380 | |
---|
381 | bool Socket::SetNonblocking(bool bNb) |
---|
382 | { |
---|
383 | #ifdef _WIN32 |
---|
384 | unsigned long l = bNb ? 1 : 0; |
---|
385 | int n = ioctlsocket(m_socket, FIONBIO, &l); |
---|
386 | if (n != 0) |
---|
387 | { |
---|
388 | Handler().LogError(this, "ioctlsocket(FIONBIO)", Errno, ""); |
---|
389 | return false; |
---|
390 | } |
---|
391 | return true; |
---|
392 | #else |
---|
393 | if (bNb) |
---|
394 | { |
---|
395 | if (fcntl(m_socket, F_SETFL, O_NONBLOCK) == -1) |
---|
396 | { |
---|
397 | Handler().LogError(this, "fcntl(F_SETFL, O_NONBLOCK)", Errno, StrError(Errno), LOG_LEVEL_ERROR); |
---|
398 | return false; |
---|
399 | } |
---|
400 | } |
---|
401 | else |
---|
402 | { |
---|
403 | if (fcntl(m_socket, F_SETFL, 0) == -1) |
---|
404 | { |
---|
405 | Handler().LogError(this, "fcntl(F_SETFL, 0)", Errno, StrError(Errno), LOG_LEVEL_ERROR); |
---|
406 | return false; |
---|
407 | } |
---|
408 | } |
---|
409 | return true; |
---|
410 | #endif |
---|
411 | } |
---|
412 | |
---|
413 | |
---|
414 | bool Socket::SetNonblocking(bool bNb, SOCKET s) |
---|
415 | { |
---|
416 | #ifdef _WIN32 |
---|
417 | unsigned long l = bNb ? 1 : 0; |
---|
418 | int n = ioctlsocket(s, FIONBIO, &l); |
---|
419 | if (n != 0) |
---|
420 | { |
---|
421 | Handler().LogError(this, "ioctlsocket(FIONBIO)", Errno, ""); |
---|
422 | return false; |
---|
423 | } |
---|
424 | return true; |
---|
425 | #else |
---|
426 | if (bNb) |
---|
427 | { |
---|
428 | if (fcntl(s, F_SETFL, O_NONBLOCK) == -1) |
---|
429 | { |
---|
430 | Handler().LogError(this, "fcntl(F_SETFL, O_NONBLOCK)", Errno, StrError(Errno), LOG_LEVEL_ERROR); |
---|
431 | return false; |
---|
432 | } |
---|
433 | } |
---|
434 | else |
---|
435 | { |
---|
436 | if (fcntl(s, F_SETFL, 0) == -1) |
---|
437 | { |
---|
438 | Handler().LogError(this, "fcntl(F_SETFL, 0)", Errno, StrError(Errno), LOG_LEVEL_ERROR); |
---|
439 | return false; |
---|
440 | } |
---|
441 | } |
---|
442 | return true; |
---|
443 | #endif |
---|
444 | } |
---|
445 | |
---|
446 | |
---|
447 | void Socket::Set(bool bRead, bool bWrite, bool bException) |
---|
448 | { |
---|
449 | Handler().Set(m_socket, bRead, bWrite, bException); |
---|
450 | } |
---|
451 | |
---|
452 | |
---|
453 | bool Socket::Ready() |
---|
454 | { |
---|
455 | if (m_socket != INVALID_SOCKET && !CloseAndDelete()) |
---|
456 | return true; |
---|
457 | return false; |
---|
458 | } |
---|
459 | |
---|
460 | |
---|
461 | void Socket::OnLine(const std::string& ) |
---|
462 | { |
---|
463 | } |
---|
464 | |
---|
465 | |
---|
466 | void Socket::OnConnectFailed() |
---|
467 | { |
---|
468 | } |
---|
469 | |
---|
470 | |
---|
471 | Socket *Socket::GetParent() |
---|
472 | { |
---|
473 | return m_parent; |
---|
474 | } |
---|
475 | |
---|
476 | |
---|
477 | void Socket::SetParent(Socket *x) |
---|
478 | { |
---|
479 | m_parent = x; |
---|
480 | } |
---|
481 | |
---|
482 | |
---|
483 | port_t Socket::GetPort() |
---|
484 | { |
---|
485 | Handler().LogError(this, "GetPort", 0, "GetPort only implemented for ListenSocket", LOG_LEVEL_WARNING); |
---|
486 | return 0; |
---|
487 | } |
---|
488 | |
---|
489 | |
---|
490 | bool Socket::OnConnectRetry() |
---|
491 | { |
---|
492 | return true; |
---|
493 | } |
---|
494 | |
---|
495 | |
---|
496 | #ifdef ENABLE_RECONNECT |
---|
497 | void Socket::OnReconnect() |
---|
498 | { |
---|
499 | } |
---|
500 | #endif |
---|
501 | |
---|
502 | |
---|
503 | time_t Socket::Uptime() |
---|
504 | { |
---|
505 | return time(NULL) - m_tCreate; |
---|
506 | } |
---|
507 | |
---|
508 | |
---|
509 | #ifdef ENABLE_IPV6 |
---|
510 | void Socket::SetIpv6(bool x) |
---|
511 | { |
---|
512 | m_ipv6 = x; |
---|
513 | } |
---|
514 | |
---|
515 | |
---|
516 | bool Socket::IsIpv6() |
---|
517 | { |
---|
518 | return m_ipv6; |
---|
519 | } |
---|
520 | #endif |
---|
521 | |
---|
522 | |
---|
523 | void Socket::DisableRead(bool x) |
---|
524 | { |
---|
525 | m_b_disable_read = x; |
---|
526 | } |
---|
527 | |
---|
528 | |
---|
529 | bool Socket::IsDisableRead() |
---|
530 | { |
---|
531 | return m_b_disable_read; |
---|
532 | } |
---|
533 | |
---|
534 | |
---|
535 | void Socket::SendBuf(const char *,size_t,int) |
---|
536 | { |
---|
537 | } |
---|
538 | |
---|
539 | |
---|
540 | void Socket::Send(const std::string&,int) |
---|
541 | { |
---|
542 | } |
---|
543 | |
---|
544 | |
---|
545 | void Socket::SetConnected(bool x) |
---|
546 | { |
---|
547 | m_connected = x; |
---|
548 | } |
---|
549 | |
---|
550 | |
---|
551 | bool Socket::IsConnected() |
---|
552 | { |
---|
553 | return m_connected; |
---|
554 | } |
---|
555 | |
---|
556 | |
---|
557 | void Socket::OnDisconnect() |
---|
558 | { |
---|
559 | } |
---|
560 | |
---|
561 | |
---|
562 | void Socket::SetLost() |
---|
563 | { |
---|
564 | m_bLost = true; |
---|
565 | } |
---|
566 | |
---|
567 | |
---|
568 | bool Socket::Lost() |
---|
569 | { |
---|
570 | return m_bLost; |
---|
571 | } |
---|
572 | |
---|
573 | |
---|
574 | void Socket::SetErasedByHandler(bool x) |
---|
575 | { |
---|
576 | m_b_erased_by_handler = x; |
---|
577 | } |
---|
578 | |
---|
579 | |
---|
580 | bool Socket::ErasedByHandler() |
---|
581 | { |
---|
582 | return m_b_erased_by_handler; |
---|
583 | } |
---|
584 | |
---|
585 | |
---|
586 | time_t Socket::TimeSinceClose() |
---|
587 | { |
---|
588 | return time(NULL) - m_tClose; |
---|
589 | } |
---|
590 | |
---|
591 | |
---|
592 | void Socket::SetClientRemoteAddress(SocketAddress& ad) |
---|
593 | { |
---|
594 | if (!ad.IsValid()) |
---|
595 | { |
---|
596 | Handler().LogError(this, "SetClientRemoteAddress", 0, "remote address not valid", LOG_LEVEL_ERROR); |
---|
597 | } |
---|
598 | m_client_remote_address = ad.GetCopy(); |
---|
599 | } |
---|
600 | |
---|
601 | |
---|
602 | std::auto_ptr<SocketAddress> Socket::GetClientRemoteAddress() |
---|
603 | { |
---|
604 | if (!m_client_remote_address.get()) |
---|
605 | { |
---|
606 | Handler().LogError(this, "GetClientRemoteAddress", 0, "remote address not yet set", LOG_LEVEL_ERROR); |
---|
607 | } |
---|
608 | return m_client_remote_address -> GetCopy(); |
---|
609 | } |
---|
610 | |
---|
611 | |
---|
612 | uint64_t Socket::GetBytesSent(bool) |
---|
613 | { |
---|
614 | return 0; |
---|
615 | } |
---|
616 | |
---|
617 | |
---|
618 | uint64_t Socket::GetBytesReceived(bool) |
---|
619 | { |
---|
620 | return 0; |
---|
621 | } |
---|
622 | |
---|
623 | |
---|
624 | #ifdef HAVE_OPENSSL |
---|
625 | void Socket::OnSSLConnect() |
---|
626 | { |
---|
627 | } |
---|
628 | |
---|
629 | |
---|
630 | void Socket::OnSSLAccept() |
---|
631 | { |
---|
632 | } |
---|
633 | |
---|
634 | |
---|
635 | bool Socket::SSLNegotiate() |
---|
636 | { |
---|
637 | return false; |
---|
638 | } |
---|
639 | |
---|
640 | |
---|
641 | bool Socket::IsSSL() |
---|
642 | { |
---|
643 | return m_b_enable_ssl; |
---|
644 | } |
---|
645 | |
---|
646 | |
---|
647 | void Socket::EnableSSL(bool x) |
---|
648 | { |
---|
649 | m_b_enable_ssl = x; |
---|
650 | } |
---|
651 | |
---|
652 | |
---|
653 | bool Socket::IsSSLNegotiate() |
---|
654 | { |
---|
655 | return m_b_ssl; |
---|
656 | } |
---|
657 | |
---|
658 | |
---|
659 | void Socket::SetSSLNegotiate(bool x) |
---|
660 | { |
---|
661 | m_b_ssl = x; |
---|
662 | } |
---|
663 | |
---|
664 | |
---|
665 | bool Socket::IsSSLServer() |
---|
666 | { |
---|
667 | return m_b_ssl_server; |
---|
668 | } |
---|
669 | |
---|
670 | |
---|
671 | void Socket::SetSSLServer(bool x) |
---|
672 | { |
---|
673 | m_b_ssl_server = x; |
---|
674 | } |
---|
675 | |
---|
676 | |
---|
677 | void Socket::OnSSLConnectFailed() |
---|
678 | { |
---|
679 | } |
---|
680 | |
---|
681 | |
---|
682 | void Socket::OnSSLAcceptFailed() |
---|
683 | { |
---|
684 | } |
---|
685 | #endif // HAVE_OPENSSL |
---|
686 | |
---|
687 | |
---|
688 | #ifdef ENABLE_POOL |
---|
689 | void Socket::CopyConnection(Socket *sock) |
---|
690 | { |
---|
691 | Attach( sock -> GetSocket() ); |
---|
692 | #ifdef ENABLE_IPV6 |
---|
693 | SetIpv6( sock -> IsIpv6() ); |
---|
694 | #endif |
---|
695 | SetSocketType( sock -> GetSocketType() ); |
---|
696 | SetSocketProtocol( sock -> GetSocketProtocol() ); |
---|
697 | |
---|
698 | SetClientRemoteAddress( *sock -> GetClientRemoteAddress() ); |
---|
699 | SetRemoteAddress( *sock -> GetRemoteSocketAddress() ); |
---|
700 | } |
---|
701 | |
---|
702 | |
---|
703 | void Socket::SetIsClient() |
---|
704 | { |
---|
705 | m_bClient = true; |
---|
706 | } |
---|
707 | |
---|
708 | |
---|
709 | void Socket::SetSocketType(int x) |
---|
710 | { |
---|
711 | m_socket_type = x; |
---|
712 | } |
---|
713 | |
---|
714 | |
---|
715 | int Socket::GetSocketType() |
---|
716 | { |
---|
717 | return m_socket_type; |
---|
718 | } |
---|
719 | |
---|
720 | |
---|
721 | void Socket::SetSocketProtocol(const std::string& x) |
---|
722 | { |
---|
723 | m_socket_protocol = x; |
---|
724 | } |
---|
725 | |
---|
726 | |
---|
727 | const std::string& Socket::GetSocketProtocol() |
---|
728 | { |
---|
729 | return m_socket_protocol; |
---|
730 | } |
---|
731 | |
---|
732 | |
---|
733 | void Socket::SetRetain() |
---|
734 | { |
---|
735 | if (m_bClient) m_bRetain = true; |
---|
736 | } |
---|
737 | |
---|
738 | |
---|
739 | bool Socket::Retain() |
---|
740 | { |
---|
741 | return m_bRetain; |
---|
742 | } |
---|
743 | |
---|
744 | |
---|
745 | #endif // ENABLE_POOL |
---|
746 | |
---|
747 | |
---|
748 | #ifdef ENABLE_SOCKS4 |
---|
749 | void Socket::OnSocks4Connect() |
---|
750 | { |
---|
751 | Handler().LogError(this, "OnSocks4Connect", 0, "Use with TcpSocket only"); |
---|
752 | } |
---|
753 | |
---|
754 | |
---|
755 | void Socket::OnSocks4ConnectFailed() |
---|
756 | { |
---|
757 | Handler().LogError(this, "OnSocks4ConnectFailed", 0, "Use with TcpSocket only"); |
---|
758 | } |
---|
759 | |
---|
760 | |
---|
761 | bool Socket::OnSocks4Read() |
---|
762 | { |
---|
763 | Handler().LogError(this, "OnSocks4Read", 0, "Use with TcpSocket only"); |
---|
764 | return true; |
---|
765 | } |
---|
766 | |
---|
767 | |
---|
768 | void Socket::SetSocks4Host(const std::string& host) |
---|
769 | { |
---|
770 | Utility::u2ip(host, m_socks4_host); |
---|
771 | } |
---|
772 | |
---|
773 | |
---|
774 | bool Socket::Socks4() |
---|
775 | { |
---|
776 | return m_bSocks4; |
---|
777 | } |
---|
778 | |
---|
779 | |
---|
780 | void Socket::SetSocks4(bool x) |
---|
781 | { |
---|
782 | m_bSocks4 = x; |
---|
783 | } |
---|
784 | |
---|
785 | |
---|
786 | void Socket::SetSocks4Host(ipaddr_t a) |
---|
787 | { |
---|
788 | m_socks4_host = a; |
---|
789 | } |
---|
790 | |
---|
791 | |
---|
792 | void Socket::SetSocks4Port(port_t p) |
---|
793 | { |
---|
794 | m_socks4_port = p; |
---|
795 | } |
---|
796 | |
---|
797 | |
---|
798 | void Socket::SetSocks4Userid(const std::string& x) |
---|
799 | { |
---|
800 | m_socks4_userid = x; |
---|
801 | } |
---|
802 | |
---|
803 | |
---|
804 | ipaddr_t Socket::GetSocks4Host() |
---|
805 | { |
---|
806 | return m_socks4_host; |
---|
807 | } |
---|
808 | |
---|
809 | |
---|
810 | port_t Socket::GetSocks4Port() |
---|
811 | { |
---|
812 | return m_socks4_port; |
---|
813 | } |
---|
814 | |
---|
815 | |
---|
816 | const std::string& Socket::GetSocks4Userid() |
---|
817 | { |
---|
818 | return m_socks4_userid; |
---|
819 | } |
---|
820 | #endif // ENABLE_SOCKS4 |
---|
821 | |
---|
822 | |
---|
823 | #ifdef ENABLE_DETACH |
---|
824 | bool Socket::Detach() |
---|
825 | { |
---|
826 | if (!DeleteByHandler()) |
---|
827 | return false; |
---|
828 | if (m_pThread) |
---|
829 | return false; |
---|
830 | if (m_detached) |
---|
831 | return false; |
---|
832 | SetDetach(); |
---|
833 | return true; |
---|
834 | } |
---|
835 | |
---|
836 | |
---|
837 | void Socket::DetachSocket() |
---|
838 | { |
---|
839 | SetDetached(); |
---|
840 | m_pThread = new SocketThread(this); |
---|
841 | m_pThread -> SetRelease(true); |
---|
842 | } |
---|
843 | |
---|
844 | |
---|
845 | void Socket::OnDetached() |
---|
846 | { |
---|
847 | } |
---|
848 | |
---|
849 | |
---|
850 | void Socket::SetDetach(bool x) |
---|
851 | { |
---|
852 | Handler().AddList(m_socket, LIST_DETACH, x); |
---|
853 | m_detach = x; |
---|
854 | } |
---|
855 | |
---|
856 | |
---|
857 | bool Socket::IsDetach() |
---|
858 | { |
---|
859 | return m_detach; |
---|
860 | } |
---|
861 | |
---|
862 | |
---|
863 | void Socket::SetDetached(bool x) |
---|
864 | { |
---|
865 | m_detached = x; |
---|
866 | } |
---|
867 | |
---|
868 | |
---|
869 | const bool Socket::IsDetached() const |
---|
870 | { |
---|
871 | return m_detached; |
---|
872 | } |
---|
873 | |
---|
874 | |
---|
875 | void Socket::SetSlaveHandler(ISocketHandler *p) |
---|
876 | { |
---|
877 | m_slave_handler = p; |
---|
878 | } |
---|
879 | |
---|
880 | |
---|
881 | Socket::SocketThread::SocketThread(Socket *p) |
---|
882 | :Thread(false) |
---|
883 | ,m_socket(p) |
---|
884 | { |
---|
885 | // Creator will release |
---|
886 | } |
---|
887 | |
---|
888 | |
---|
889 | Socket::SocketThread::~SocketThread() |
---|
890 | { |
---|
891 | if (IsRunning()) |
---|
892 | { |
---|
893 | SetRelease(true); |
---|
894 | SetRunning(false); |
---|
895 | #ifdef _WIN32 |
---|
896 | Sleep(1000); |
---|
897 | #else |
---|
898 | sleep(1); |
---|
899 | #endif |
---|
900 | } |
---|
901 | } |
---|
902 | |
---|
903 | |
---|
904 | void Socket::SocketThread::Run() |
---|
905 | { |
---|
906 | SocketHandler h; |
---|
907 | h.SetSlave(); |
---|
908 | h.Add(m_socket); |
---|
909 | m_socket -> SetSlaveHandler(&h); |
---|
910 | m_socket -> OnDetached(); |
---|
911 | while (h.GetCount() && IsRunning()) |
---|
912 | { |
---|
913 | h.Select(0, 500000); |
---|
914 | } |
---|
915 | // m_socket now deleted oops |
---|
916 | // yeah oops m_socket delete its socket thread, that means this |
---|
917 | // so Socket will no longer delete its socket thread, instead we do this: |
---|
918 | SetDeleteOnExit(); |
---|
919 | } |
---|
920 | #endif // ENABLE_DETACH |
---|
921 | |
---|
922 | |
---|
923 | #ifdef ENABLE_RESOLVER |
---|
924 | int Socket::Resolve(const std::string& host,port_t port) |
---|
925 | { |
---|
926 | return Handler().Resolve(this, host, port); |
---|
927 | } |
---|
928 | |
---|
929 | |
---|
930 | #ifdef ENABLE_IPV6 |
---|
931 | int Socket::Resolve6(const std::string& host,port_t port) |
---|
932 | { |
---|
933 | return Handler().Resolve6(this, host, port); |
---|
934 | } |
---|
935 | #endif |
---|
936 | |
---|
937 | |
---|
938 | int Socket::Resolve(ipaddr_t a) |
---|
939 | { |
---|
940 | return Handler().Resolve(this, a); |
---|
941 | } |
---|
942 | |
---|
943 | |
---|
944 | #ifdef ENABLE_IPV6 |
---|
945 | int Socket::Resolve(in6_addr& a) |
---|
946 | { |
---|
947 | return Handler().Resolve(this, a); |
---|
948 | } |
---|
949 | #endif |
---|
950 | |
---|
951 | |
---|
952 | void Socket::OnResolved(int,ipaddr_t,port_t) |
---|
953 | { |
---|
954 | } |
---|
955 | |
---|
956 | |
---|
957 | #ifdef ENABLE_IPV6 |
---|
958 | void Socket::OnResolved(int,in6_addr&,port_t) |
---|
959 | { |
---|
960 | } |
---|
961 | #endif |
---|
962 | |
---|
963 | |
---|
964 | void Socket::OnReverseResolved(int,const std::string&) |
---|
965 | { |
---|
966 | } |
---|
967 | |
---|
968 | |
---|
969 | void Socket::OnResolveFailed(int) |
---|
970 | { |
---|
971 | } |
---|
972 | #endif // ENABLE_RESOLVER |
---|
973 | |
---|
974 | |
---|
975 | /* IP options */ |
---|
976 | |
---|
977 | |
---|
978 | bool Socket::SetIpOptions(const void *p, socklen_t len) |
---|
979 | { |
---|
980 | #ifdef IP_OPTIONS |
---|
981 | if (setsockopt(GetSocket(), IPPROTO_IP, IP_OPTIONS, (char *)p, len) == -1) |
---|
982 | { |
---|
983 | Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_OPTIONS)", Errno, StrError(Errno), LOG_LEVEL_FATAL); |
---|
984 | return false; |
---|
985 | } |
---|
986 | return true; |
---|
987 | #else |
---|
988 | Handler().LogError(this, "ip option not available", 0, "IP_OPTIONS", LOG_LEVEL_INFO); |
---|
989 | return false; |
---|
990 | #endif |
---|
991 | } |
---|
992 | |
---|
993 | |
---|
994 | #ifdef IP_PKTINFO |
---|
995 | bool Socket::SetIpPktinfo(bool x) |
---|
996 | { |
---|
997 | int optval = x ? 1 : 0; |
---|
998 | if (setsockopt(GetSocket(), IPPROTO_IP, IP_PKTINFO, (char *)&optval, sizeof(optval)) == -1) |
---|
999 | { |
---|
1000 | Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_PKTINFO)", Errno, StrError(Errno), LOG_LEVEL_FATAL); |
---|
1001 | return false; |
---|
1002 | } |
---|
1003 | return true; |
---|
1004 | } |
---|
1005 | #endif |
---|
1006 | |
---|
1007 | |
---|
1008 | #ifdef IP_RECVTOS |
---|
1009 | bool Socket::SetIpRecvTOS(bool x) |
---|
1010 | { |
---|
1011 | int optval = x ? 1 : 0; |
---|
1012 | if (setsockopt(GetSocket(), IPPROTO_IP, IP_RECVTOS, (char *)&optval, sizeof(optval)) == -1) |
---|
1013 | { |
---|
1014 | Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_RECVTOS)", Errno, StrError(Errno), LOG_LEVEL_FATAL); |
---|
1015 | return false; |
---|
1016 | } |
---|
1017 | return true; |
---|
1018 | } |
---|
1019 | #endif |
---|
1020 | |
---|
1021 | |
---|
1022 | #ifdef IP_RECVTTL |
---|
1023 | bool Socket::SetIpRecvTTL(bool x) |
---|
1024 | { |
---|
1025 | int optval = x ? 1 : 0; |
---|
1026 | if (setsockopt(GetSocket(), IPPROTO_IP, IP_RECVTTL, (char *)&optval, sizeof(optval)) == -1) |
---|
1027 | { |
---|
1028 | Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_RECVTTL)", Errno, StrError(Errno), LOG_LEVEL_FATAL); |
---|
1029 | return false; |
---|
1030 | } |
---|
1031 | return true; |
---|
1032 | } |
---|
1033 | #endif |
---|
1034 | |
---|
1035 | |
---|
1036 | #ifdef IP_RECVOPTS |
---|
1037 | bool Socket::SetIpRecvopts(bool x) |
---|
1038 | { |
---|
1039 | int optval = x ? 1 : 0; |
---|
1040 | if (setsockopt(GetSocket(), IPPROTO_IP, IP_RECVOPTS, (char *)&optval, sizeof(optval)) == -1) |
---|
1041 | { |
---|
1042 | Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_RECVOPTS)", Errno, StrError(Errno), LOG_LEVEL_FATAL); |
---|
1043 | return false; |
---|
1044 | } |
---|
1045 | return true; |
---|
1046 | } |
---|
1047 | #endif |
---|
1048 | |
---|
1049 | |
---|
1050 | #ifdef IP_RETOPTS |
---|
1051 | bool Socket::SetIpRetopts(bool x) |
---|
1052 | { |
---|
1053 | int optval = x ? 1 : 0; |
---|
1054 | if (setsockopt(GetSocket(), IPPROTO_IP, IP_RETOPTS, (char *)&optval, sizeof(optval)) == -1) |
---|
1055 | { |
---|
1056 | Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_RETOPTS)", Errno, StrError(Errno), LOG_LEVEL_FATAL); |
---|
1057 | return false; |
---|
1058 | } |
---|
1059 | return true; |
---|
1060 | } |
---|
1061 | #endif |
---|
1062 | |
---|
1063 | |
---|
1064 | bool Socket::SetIpTOS(unsigned char tos) |
---|
1065 | { |
---|
1066 | #ifdef IP_TOS |
---|
1067 | if (setsockopt(GetSocket(), IPPROTO_IP, IP_TOS, (char *)&tos, sizeof(tos)) == -1) |
---|
1068 | { |
---|
1069 | Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_TOS)", Errno, StrError(Errno), LOG_LEVEL_FATAL); |
---|
1070 | return false; |
---|
1071 | } |
---|
1072 | return true; |
---|
1073 | #else |
---|
1074 | Handler().LogError(this, "ip option not available", 0, "IP_TOS", LOG_LEVEL_INFO); |
---|
1075 | return false; |
---|
1076 | #endif |
---|
1077 | } |
---|
1078 | |
---|
1079 | |
---|
1080 | unsigned char Socket::IpTOS() |
---|
1081 | { |
---|
1082 | unsigned char tos = 0; |
---|
1083 | #ifdef IP_TOS |
---|
1084 | socklen_t len = sizeof(tos); |
---|
1085 | if (getsockopt(GetSocket(), IPPROTO_IP, IP_TOS, (char *)&tos, &len) == -1) |
---|
1086 | { |
---|
1087 | Handler().LogError(this, "getsockopt(IPPROTO_IP, IP_TOS)", Errno, StrError(Errno), LOG_LEVEL_FATAL); |
---|
1088 | } |
---|
1089 | #else |
---|
1090 | Handler().LogError(this, "ip option not available", 0, "IP_TOS", LOG_LEVEL_INFO); |
---|
1091 | #endif |
---|
1092 | return tos; |
---|
1093 | } |
---|
1094 | |
---|
1095 | |
---|
1096 | bool Socket::SetIpTTL(int ttl) |
---|
1097 | { |
---|
1098 | #ifdef IP_TTL |
---|
1099 | if (setsockopt(GetSocket(), IPPROTO_IP, IP_TTL, (char *)&ttl, sizeof(ttl)) == -1) |
---|
1100 | { |
---|
1101 | Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_TTL)", Errno, StrError(Errno), LOG_LEVEL_FATAL); |
---|
1102 | return false; |
---|
1103 | } |
---|
1104 | return true; |
---|
1105 | #else |
---|
1106 | Handler().LogError(this, "ip option not available", 0, "IP_TTL", LOG_LEVEL_INFO); |
---|
1107 | return false; |
---|
1108 | #endif |
---|
1109 | } |
---|
1110 | |
---|
1111 | |
---|
1112 | int Socket::IpTTL() |
---|
1113 | { |
---|
1114 | int ttl = 0; |
---|
1115 | #ifdef IP_TTL |
---|
1116 | socklen_t len = sizeof(ttl); |
---|
1117 | if (getsockopt(GetSocket(), IPPROTO_IP, IP_TTL, (char *)&ttl, &len) == -1) |
---|
1118 | { |
---|
1119 | Handler().LogError(this, "getsockopt(IPPROTO_IP, IP_TTL)", Errno, StrError(Errno), LOG_LEVEL_FATAL); |
---|
1120 | } |
---|
1121 | #else |
---|
1122 | Handler().LogError(this, "ip option not available", 0, "IP_TTL", LOG_LEVEL_INFO); |
---|
1123 | #endif |
---|
1124 | return ttl; |
---|
1125 | } |
---|
1126 | |
---|
1127 | |
---|
1128 | bool Socket::SetIpHdrincl(bool x) |
---|
1129 | { |
---|
1130 | #ifdef IP_HDRINCL |
---|
1131 | int optval = x ? 1 : 0; |
---|
1132 | if (setsockopt(GetSocket(), IPPROTO_IP, IP_HDRINCL, (char *)&optval, sizeof(optval)) == -1) |
---|
1133 | { |
---|
1134 | Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_HDRINCL)", Errno, StrError(Errno), LOG_LEVEL_FATAL); |
---|
1135 | return false; |
---|
1136 | } |
---|
1137 | return true; |
---|
1138 | #else |
---|
1139 | Handler().LogError(this, "ip option not available", 0, "IP_HDRINCL", LOG_LEVEL_INFO); |
---|
1140 | return false; |
---|
1141 | #endif |
---|
1142 | } |
---|
1143 | |
---|
1144 | |
---|
1145 | #ifdef IP_RECVERR |
---|
1146 | bool Socket::SetIpRecverr(bool x) |
---|
1147 | { |
---|
1148 | int optval = x ? 1 : 0; |
---|
1149 | if (setsockopt(GetSocket(), IPPROTO_IP, IP_RECVERR, (char *)&optval, sizeof(optval)) == -1) |
---|
1150 | { |
---|
1151 | Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_RECVERR)", Errno, StrError(Errno), LOG_LEVEL_FATAL); |
---|
1152 | return false; |
---|
1153 | } |
---|
1154 | return true; |
---|
1155 | } |
---|
1156 | #endif |
---|
1157 | |
---|
1158 | |
---|
1159 | #ifdef IP_MTU_DISCOVER |
---|
1160 | bool Socket::SetIpMtudiscover(bool x) |
---|
1161 | { |
---|
1162 | int optval = x ? 1 : 0; |
---|
1163 | if (setsockopt(GetSocket(), IPPROTO_IP, IP_MTU_DISCOVER, (char *)&optval, sizeof(optval)) == -1) |
---|
1164 | { |
---|
1165 | Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_MTU_DISCOVER)", Errno, StrError(Errno), LOG_LEVEL_FATAL); |
---|
1166 | return false; |
---|
1167 | } |
---|
1168 | return true; |
---|
1169 | } |
---|
1170 | #endif |
---|
1171 | |
---|
1172 | |
---|
1173 | #ifdef IP_MTU |
---|
1174 | int Socket::IpMtu() |
---|
1175 | { |
---|
1176 | int mtu = 0; |
---|
1177 | socklen_t len = sizeof(mtu); |
---|
1178 | if (getsockopt(GetSocket(), IPPROTO_IP, IP_MTU, (char *)&mtu, &len) == -1) |
---|
1179 | { |
---|
1180 | Handler().LogError(this, "getsockopt(IPPROTO_IP, IP_MTU)", Errno, StrError(Errno), LOG_LEVEL_FATAL); |
---|
1181 | } |
---|
1182 | return mtu; |
---|
1183 | } |
---|
1184 | #endif |
---|
1185 | |
---|
1186 | |
---|
1187 | #ifdef IP_ROUTER_ALERT |
---|
1188 | bool Socket::SetIpRouterAlert(bool x) |
---|
1189 | { |
---|
1190 | int optval = x ? 1 : 0; |
---|
1191 | if (setsockopt(GetSocket(), IPPROTO_IP, IP_ROUTER_ALERT, (char *)&optval, sizeof(optval)) == -1) |
---|
1192 | { |
---|
1193 | Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_ROUTER_ALERT)", Errno, StrError(Errno), LOG_LEVEL_FATAL); |
---|
1194 | return false; |
---|
1195 | } |
---|
1196 | return true; |
---|
1197 | } |
---|
1198 | #endif |
---|
1199 | |
---|
1200 | |
---|
1201 | bool Socket::SetIpMulticastTTL(int ttl) |
---|
1202 | { |
---|
1203 | #ifdef IP_MULTICAST_TTL |
---|
1204 | if (setsockopt(GetSocket(), IPPROTO_IP, IP_MULTICAST_TTL, (char *)&ttl, sizeof(ttl)) == -1) |
---|
1205 | { |
---|
1206 | Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_MULTICAST_TTL)", Errno, StrError(Errno), LOG_LEVEL_FATAL); |
---|
1207 | return false; |
---|
1208 | } |
---|
1209 | return true; |
---|
1210 | #else |
---|
1211 | Handler().LogError(this, "ip option not available", 0, "IP_MULTICAST_TTL", LOG_LEVEL_INFO); |
---|
1212 | return false; |
---|
1213 | #endif |
---|
1214 | } |
---|
1215 | |
---|
1216 | |
---|
1217 | int Socket::IpMulticastTTL() |
---|
1218 | { |
---|
1219 | int ttl = 0; |
---|
1220 | #ifdef IP_MULTICAST_TTL |
---|
1221 | socklen_t len = sizeof(ttl); |
---|
1222 | if (getsockopt(GetSocket(), IPPROTO_IP, IP_MULTICAST_TTL, (char *)&ttl, &len) == -1) |
---|
1223 | { |
---|
1224 | Handler().LogError(this, "getsockopt(IPPROTO_IP, IP_MULTICAST_TTL)", Errno, StrError(Errno), LOG_LEVEL_FATAL); |
---|
1225 | } |
---|
1226 | #else |
---|
1227 | Handler().LogError(this, "ip option not available", 0, "IP_MULTICAST_TTL", LOG_LEVEL_INFO); |
---|
1228 | #endif |
---|
1229 | return ttl; |
---|
1230 | } |
---|
1231 | |
---|
1232 | |
---|
1233 | bool Socket::SetMulticastLoop(bool x) |
---|
1234 | { |
---|
1235 | #ifdef IP_MULTICAST_LOOP |
---|
1236 | int optval = x ? 1 : 0; |
---|
1237 | if (setsockopt(GetSocket(), IPPROTO_IP, IP_MULTICAST_LOOP, (char *)&optval, sizeof(optval)) == -1) |
---|
1238 | { |
---|
1239 | Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_MULTICAST_LOOP)", Errno, StrError(Errno), LOG_LEVEL_FATAL); |
---|
1240 | return false; |
---|
1241 | } |
---|
1242 | return true; |
---|
1243 | #else |
---|
1244 | Handler().LogError(this, "ip option not available", 0, "IP_MULTICAST_LOOP", LOG_LEVEL_INFO); |
---|
1245 | return false; |
---|
1246 | #endif |
---|
1247 | } |
---|
1248 | |
---|
1249 | |
---|
1250 | #ifdef LINUX |
---|
1251 | bool Socket::IpAddMembership(struct ip_mreqn& ref) |
---|
1252 | { |
---|
1253 | #ifdef IP_ADD_MEMBERSHIP |
---|
1254 | if (setsockopt(GetSocket(), IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&ref, sizeof(struct ip_mreqn)) == -1) |
---|
1255 | { |
---|
1256 | Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_ADD_MEMBERSHIP)", Errno, StrError(Errno), LOG_LEVEL_FATAL); |
---|
1257 | return false; |
---|
1258 | } |
---|
1259 | return true; |
---|
1260 | #else |
---|
1261 | Handler().LogError(this, "ip option not available", 0, "IP_ADD_MEMBERSHIP", LOG_LEVEL_INFO); |
---|
1262 | return false; |
---|
1263 | #endif |
---|
1264 | } |
---|
1265 | #endif |
---|
1266 | |
---|
1267 | |
---|
1268 | bool Socket::IpAddMembership(struct ip_mreq& ref) |
---|
1269 | { |
---|
1270 | #ifdef IP_ADD_MEMBERSHIP |
---|
1271 | if (setsockopt(GetSocket(), IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&ref, sizeof(struct ip_mreq)) == -1) |
---|
1272 | { |
---|
1273 | Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_ADD_MEMBERSHIP)", Errno, StrError(Errno), LOG_LEVEL_FATAL); |
---|
1274 | return false; |
---|
1275 | } |
---|
1276 | return true; |
---|
1277 | #else |
---|
1278 | Handler().LogError(this, "ip option not available", 0, "IP_ADD_MEMBERSHIP", LOG_LEVEL_INFO); |
---|
1279 | return false; |
---|
1280 | #endif |
---|
1281 | } |
---|
1282 | |
---|
1283 | |
---|
1284 | #ifdef LINUX |
---|
1285 | bool Socket::IpDropMembership(struct ip_mreqn& ref) |
---|
1286 | { |
---|
1287 | #ifdef IP_DROP_MEMBERSHIP |
---|
1288 | if (setsockopt(GetSocket(), IPPROTO_IP, IP_DROP_MEMBERSHIP, (char *)&ref, sizeof(struct ip_mreqn)) == -1) |
---|
1289 | { |
---|
1290 | Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_DROP_MEMBERSHIP)", Errno, StrError(Errno), LOG_LEVEL_FATAL); |
---|
1291 | return false; |
---|
1292 | } |
---|
1293 | return true; |
---|
1294 | #else |
---|
1295 | Handler().LogError(this, "ip option not available", 0, "IP_DROP_MEMBERSHIP", LOG_LEVEL_INFO); |
---|
1296 | return false; |
---|
1297 | #endif |
---|
1298 | } |
---|
1299 | #endif |
---|
1300 | |
---|
1301 | |
---|
1302 | bool Socket::IpDropMembership(struct ip_mreq& ref) |
---|
1303 | { |
---|
1304 | #ifdef IP_DROP_MEMBERSHIP |
---|
1305 | if (setsockopt(GetSocket(), IPPROTO_IP, IP_DROP_MEMBERSHIP, (char *)&ref, sizeof(struct ip_mreq)) == -1) |
---|
1306 | { |
---|
1307 | Handler().LogError(this, "setsockopt(IPPROTO_IP, IP_DROP_MEMBERSHIP)", Errno, StrError(Errno), LOG_LEVEL_FATAL); |
---|
1308 | return false; |
---|
1309 | } |
---|
1310 | return true; |
---|
1311 | #else |
---|
1312 | Handler().LogError(this, "ip option not available", 0, "IP_DROP_MEMBERSHIP", LOG_LEVEL_INFO); |
---|
1313 | return false; |
---|
1314 | #endif |
---|
1315 | } |
---|
1316 | |
---|
1317 | |
---|
1318 | /* SOCKET options */ |
---|
1319 | |
---|
1320 | |
---|
1321 | bool Socket::SetSoReuseaddr(bool x) |
---|
1322 | { |
---|
1323 | #ifdef SO_REUSEADDR |
---|
1324 | int optval = x ? 1 : 0; |
---|
1325 | if (setsockopt(GetSocket(), SOL_SOCKET, SO_REUSEADDR, (char *)&optval, sizeof(optval)) == -1) |
---|
1326 | { |
---|
1327 | Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_REUSEADDR)", Errno, StrError(Errno), LOG_LEVEL_FATAL); |
---|
1328 | return false; |
---|
1329 | } |
---|
1330 | return true; |
---|
1331 | #else |
---|
1332 | Handler().LogError(this, "socket option not available", 0, "SO_REUSEADDR", LOG_LEVEL_INFO); |
---|
1333 | return false; |
---|
1334 | #endif |
---|
1335 | } |
---|
1336 | |
---|
1337 | |
---|
1338 | bool Socket::SetSoKeepalive(bool x) |
---|
1339 | { |
---|
1340 | #ifdef SO_KEEPALIVE |
---|
1341 | int optval = x ? 1 : 0; |
---|
1342 | if (setsockopt(GetSocket(), SOL_SOCKET, SO_KEEPALIVE, (char *)&optval, sizeof(optval)) == -1) |
---|
1343 | { |
---|
1344 | Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_KEEPALIVE)", Errno, StrError(Errno), LOG_LEVEL_FATAL); |
---|
1345 | return false; |
---|
1346 | } |
---|
1347 | return true; |
---|
1348 | #else |
---|
1349 | Handler().LogError(this, "socket option not available", 0, "SO_KEEPALIVE", LOG_LEVEL_INFO); |
---|
1350 | return false; |
---|
1351 | #endif |
---|
1352 | } |
---|
1353 | |
---|
1354 | |
---|
1355 | #ifdef SO_NOSIGPIPE |
---|
1356 | bool Socket::SetSoNosigpipe(bool x) |
---|
1357 | { |
---|
1358 | int optval = x ? 1 : 0; |
---|
1359 | if (setsockopt(GetSocket(), SOL_SOCKET, SO_NOSIGPIPE, (char *)&optval, sizeof(optval)) == -1) |
---|
1360 | { |
---|
1361 | Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_NOSIGPIPE)", Errno, StrError(Errno), LOG_LEVEL_FATAL); |
---|
1362 | return false; |
---|
1363 | } |
---|
1364 | return true; |
---|
1365 | } |
---|
1366 | #endif |
---|
1367 | |
---|
1368 | |
---|
1369 | bool Socket::SoAcceptconn() |
---|
1370 | { |
---|
1371 | int value = 0; |
---|
1372 | #ifdef SO_ACCEPTCONN |
---|
1373 | socklen_t len = sizeof(value); |
---|
1374 | if (getsockopt(GetSocket(), SOL_SOCKET, SO_ACCEPTCONN, (char *)&value, &len) == -1) |
---|
1375 | { |
---|
1376 | Handler().LogError(this, "getsockopt(SOL_SOCKET, SO_ACCEPTCONN)", Errno, StrError(Errno), LOG_LEVEL_FATAL); |
---|
1377 | } |
---|
1378 | #else |
---|
1379 | Handler().LogError(this, "socket option not available", 0, "SO_ACCEPTCONN", LOG_LEVEL_INFO); |
---|
1380 | #endif |
---|
1381 | return value ? true : false; |
---|
1382 | } |
---|
1383 | |
---|
1384 | |
---|
1385 | #ifdef SO_BSDCOMPAT |
---|
1386 | bool Socket::SetSoBsdcompat(bool x) |
---|
1387 | { |
---|
1388 | int optval = x ? 1 : 0; |
---|
1389 | if (setsockopt(GetSocket(), SOL_SOCKET, SO_BSDCOMPAT, (char *)&optval, sizeof(optval)) == -1) |
---|
1390 | { |
---|
1391 | Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_BSDCOMPAT)", Errno, StrError(Errno), LOG_LEVEL_FATAL); |
---|
1392 | return false; |
---|
1393 | } |
---|
1394 | return true; |
---|
1395 | } |
---|
1396 | #endif |
---|
1397 | |
---|
1398 | |
---|
1399 | #ifdef SO_BINDTODEVICE |
---|
1400 | bool Socket::SetSoBindtodevice(const std::string& intf) |
---|
1401 | { |
---|
1402 | if (setsockopt(GetSocket(), SOL_SOCKET, SO_BINDTODEVICE, (char *)intf.c_str(), intf.size()) == -1) |
---|
1403 | { |
---|
1404 | Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_BINDTODEVICE)", Errno, StrError(Errno), LOG_LEVEL_FATAL); |
---|
1405 | return false; |
---|
1406 | } |
---|
1407 | return true; |
---|
1408 | } |
---|
1409 | #endif |
---|
1410 | |
---|
1411 | |
---|
1412 | bool Socket::SetSoBroadcast(bool x) |
---|
1413 | { |
---|
1414 | #ifdef SO_BROADCAST |
---|
1415 | int optval = x ? 1 : 0; |
---|
1416 | if (setsockopt(GetSocket(), SOL_SOCKET, SO_BROADCAST, (char *)&optval, sizeof(optval)) == -1) |
---|
1417 | { |
---|
1418 | Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_BROADCAST)", Errno, StrError(Errno), LOG_LEVEL_FATAL); |
---|
1419 | return false; |
---|
1420 | } |
---|
1421 | return true; |
---|
1422 | #else |
---|
1423 | Handler().LogError(this, "socket option not available", 0, "SO_BROADCAST", LOG_LEVEL_INFO); |
---|
1424 | return false; |
---|
1425 | #endif |
---|
1426 | } |
---|
1427 | |
---|
1428 | |
---|
1429 | bool Socket::SetSoDebug(bool x) |
---|
1430 | { |
---|
1431 | #ifdef SO_DEBUG |
---|
1432 | int optval = x ? 1 : 0; |
---|
1433 | if (setsockopt(GetSocket(), SOL_SOCKET, SO_DEBUG, (char *)&optval, sizeof(optval)) == -1) |
---|
1434 | { |
---|
1435 | Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_DEBUG)", Errno, StrError(Errno), LOG_LEVEL_FATAL); |
---|
1436 | return false; |
---|
1437 | } |
---|
1438 | return true; |
---|
1439 | #else |
---|
1440 | Handler().LogError(this, "socket option not available", 0, "SO_DEBUG", LOG_LEVEL_INFO); |
---|
1441 | return false; |
---|
1442 | #endif |
---|
1443 | } |
---|
1444 | |
---|
1445 | |
---|
1446 | int Socket::SoError() |
---|
1447 | { |
---|
1448 | int value = 0; |
---|
1449 | #ifdef SO_ERROR |
---|
1450 | socklen_t len = sizeof(value); |
---|
1451 | if (getsockopt(GetSocket(), SOL_SOCKET, SO_ERROR, (char *)&value, &len) == -1) |
---|
1452 | { |
---|
1453 | Handler().LogError(this, "getsockopt(SOL_SOCKET, SO_ERROR)", Errno, StrError(Errno), LOG_LEVEL_FATAL); |
---|
1454 | } |
---|
1455 | #else |
---|
1456 | Handler().LogError(this, "socket option not available", 0, "SO_ERROR", LOG_LEVEL_INFO); |
---|
1457 | #endif |
---|
1458 | return value; |
---|
1459 | } |
---|
1460 | |
---|
1461 | |
---|
1462 | bool Socket::SetSoDontroute(bool x) |
---|
1463 | { |
---|
1464 | #ifdef SO_DONTROUTE |
---|
1465 | int optval = x ? 1 : 0; |
---|
1466 | if (setsockopt(GetSocket(), SOL_SOCKET, SO_DONTROUTE, (char *)&optval, sizeof(optval)) == -1) |
---|
1467 | { |
---|
1468 | Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_DONTROUTE)", Errno, StrError(Errno), LOG_LEVEL_FATAL); |
---|
1469 | return false; |
---|
1470 | } |
---|
1471 | return true; |
---|
1472 | #else |
---|
1473 | Handler().LogError(this, "socket option not available", 0, "SO_DONTROUTE", LOG_LEVEL_INFO); |
---|
1474 | return false; |
---|
1475 | #endif |
---|
1476 | } |
---|
1477 | |
---|
1478 | |
---|
1479 | bool Socket::SetSoLinger(int onoff, int linger) |
---|
1480 | { |
---|
1481 | #ifdef SO_LINGER |
---|
1482 | struct linger stl; |
---|
1483 | stl.l_onoff = onoff; |
---|
1484 | stl.l_linger = linger; |
---|
1485 | if (setsockopt(GetSocket(), SOL_SOCKET, SO_LINGER, (char *)&stl, sizeof(stl)) == -1) |
---|
1486 | { |
---|
1487 | Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_LINGER)", Errno, StrError(Errno), LOG_LEVEL_FATAL); |
---|
1488 | return false; |
---|
1489 | } |
---|
1490 | return true; |
---|
1491 | #else |
---|
1492 | Handler().LogError(this, "socket option not available", 0, "SO_LINGER", LOG_LEVEL_INFO); |
---|
1493 | return false; |
---|
1494 | #endif |
---|
1495 | } |
---|
1496 | |
---|
1497 | |
---|
1498 | bool Socket::SetSoOobinline(bool x) |
---|
1499 | { |
---|
1500 | #ifdef SO_OOBINLINE |
---|
1501 | int optval = x ? 1 : 0; |
---|
1502 | if (setsockopt(GetSocket(), SOL_SOCKET, SO_OOBINLINE, (char *)&optval, sizeof(optval)) == -1) |
---|
1503 | { |
---|
1504 | Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_OOBINLINE)", Errno, StrError(Errno), LOG_LEVEL_FATAL); |
---|
1505 | return false; |
---|
1506 | } |
---|
1507 | return true; |
---|
1508 | #else |
---|
1509 | Handler().LogError(this, "socket option not available", 0, "SO_OOBINLINE", LOG_LEVEL_INFO); |
---|
1510 | return false; |
---|
1511 | #endif |
---|
1512 | } |
---|
1513 | |
---|
1514 | |
---|
1515 | #ifdef SO_PASSCRED |
---|
1516 | bool Socket::SetSoPasscred(bool x) |
---|
1517 | { |
---|
1518 | int optval = x ? 1 : 0; |
---|
1519 | if (setsockopt(GetSocket(), SOL_SOCKET, SO_PASSCRED, (char *)&optval, sizeof(optval)) == -1) |
---|
1520 | { |
---|
1521 | Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_PASSCRED)", Errno, StrError(Errno), LOG_LEVEL_FATAL); |
---|
1522 | return false; |
---|
1523 | } |
---|
1524 | return true; |
---|
1525 | } |
---|
1526 | #endif |
---|
1527 | |
---|
1528 | |
---|
1529 | #ifdef SO_PEERCRED |
---|
1530 | bool Socket::SoPeercred(struct ucred& ucr) |
---|
1531 | { |
---|
1532 | if (setsockopt(GetSocket(), SOL_SOCKET, SO_PEERCRED, (char *)&ucr, sizeof(ucr)) == -1) |
---|
1533 | { |
---|
1534 | Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_PEERCRED)", Errno, StrError(Errno), LOG_LEVEL_FATAL); |
---|
1535 | return false; |
---|
1536 | } |
---|
1537 | return true; |
---|
1538 | } |
---|
1539 | #endif |
---|
1540 | |
---|
1541 | |
---|
1542 | #ifdef SO_PRIORITY |
---|
1543 | bool Socket::SetSoPriority(int x) |
---|
1544 | { |
---|
1545 | if (setsockopt(GetSocket(), SOL_SOCKET, SO_PRIORITY, (char *)&x, sizeof(x)) == -1) |
---|
1546 | { |
---|
1547 | Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_PRIORITY)", Errno, StrError(Errno), LOG_LEVEL_FATAL); |
---|
1548 | return false; |
---|
1549 | } |
---|
1550 | return true; |
---|
1551 | } |
---|
1552 | #endif |
---|
1553 | |
---|
1554 | |
---|
1555 | bool Socket::SetSoRcvlowat(int x) |
---|
1556 | { |
---|
1557 | #ifdef SO_RCVLOWAT |
---|
1558 | if (setsockopt(GetSocket(), SOL_SOCKET, SO_RCVLOWAT, (char *)&x, sizeof(x)) == -1) |
---|
1559 | { |
---|
1560 | Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_RCVLOWAT)", Errno, StrError(Errno), LOG_LEVEL_FATAL); |
---|
1561 | return false; |
---|
1562 | } |
---|
1563 | return true; |
---|
1564 | #else |
---|
1565 | Handler().LogError(this, "socket option not available", 0, "SO_RCVLOWAT", LOG_LEVEL_INFO); |
---|
1566 | return false; |
---|
1567 | #endif |
---|
1568 | } |
---|
1569 | |
---|
1570 | |
---|
1571 | bool Socket::SetSoSndlowat(int x) |
---|
1572 | { |
---|
1573 | #ifdef SO_SNDLOWAT |
---|
1574 | if (setsockopt(GetSocket(), SOL_SOCKET, SO_SNDLOWAT, (char *)&x, sizeof(x)) == -1) |
---|
1575 | { |
---|
1576 | Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_SNDLOWAT)", Errno, StrError(Errno), LOG_LEVEL_FATAL); |
---|
1577 | return false; |
---|
1578 | } |
---|
1579 | return true; |
---|
1580 | #else |
---|
1581 | Handler().LogError(this, "socket option not available", 0, "SO_SNDLOWAT", LOG_LEVEL_INFO); |
---|
1582 | return false; |
---|
1583 | #endif |
---|
1584 | } |
---|
1585 | |
---|
1586 | |
---|
1587 | bool Socket::SetSoRcvtimeo(struct timeval& tv) |
---|
1588 | { |
---|
1589 | #ifdef SO_RCVTIMEO |
---|
1590 | if (setsockopt(GetSocket(), SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(tv)) == -1) |
---|
1591 | { |
---|
1592 | Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_RCVTIMEO)", Errno, StrError(Errno), LOG_LEVEL_FATAL); |
---|
1593 | return false; |
---|
1594 | } |
---|
1595 | return true; |
---|
1596 | #else |
---|
1597 | Handler().LogError(this, "socket option not available", 0, "SO_RCVTIMEO", LOG_LEVEL_INFO); |
---|
1598 | return false; |
---|
1599 | #endif |
---|
1600 | } |
---|
1601 | |
---|
1602 | |
---|
1603 | bool Socket::SetSoSndtimeo(struct timeval& tv) |
---|
1604 | { |
---|
1605 | #ifdef SO_SNDTIMEO |
---|
1606 | if (setsockopt(GetSocket(), SOL_SOCKET, SO_SNDTIMEO, (char *)&tv, sizeof(tv)) == -1) |
---|
1607 | { |
---|
1608 | Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_SNDTIMEO)", Errno, StrError(Errno), LOG_LEVEL_FATAL); |
---|
1609 | return false; |
---|
1610 | } |
---|
1611 | return true; |
---|
1612 | #else |
---|
1613 | Handler().LogError(this, "socket option not available", 0, "SO_SNDTIMEO", LOG_LEVEL_INFO); |
---|
1614 | return false; |
---|
1615 | #endif |
---|
1616 | } |
---|
1617 | |
---|
1618 | |
---|
1619 | bool Socket::SetSoRcvbuf(int x) |
---|
1620 | { |
---|
1621 | #ifdef SO_RCVBUF |
---|
1622 | if (setsockopt(GetSocket(), SOL_SOCKET, SO_RCVBUF, (char *)&x, sizeof(x)) == -1) |
---|
1623 | { |
---|
1624 | Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_RCVBUF)", Errno, StrError(Errno), LOG_LEVEL_FATAL); |
---|
1625 | return false; |
---|
1626 | } |
---|
1627 | return true; |
---|
1628 | #else |
---|
1629 | Handler().LogError(this, "socket option not available", 0, "SO_RCVBUF", LOG_LEVEL_INFO); |
---|
1630 | return false; |
---|
1631 | #endif |
---|
1632 | } |
---|
1633 | |
---|
1634 | |
---|
1635 | int Socket::SoRcvbuf() |
---|
1636 | { |
---|
1637 | int value = 0; |
---|
1638 | #ifdef SO_RCVBUF |
---|
1639 | socklen_t len = sizeof(value); |
---|
1640 | if (getsockopt(GetSocket(), SOL_SOCKET, SO_RCVBUF, (char *)&value, &len) == -1) |
---|
1641 | { |
---|
1642 | Handler().LogError(this, "getsockopt(SOL_SOCKET, SO_RCVBUF)", Errno, StrError(Errno), LOG_LEVEL_FATAL); |
---|
1643 | } |
---|
1644 | #else |
---|
1645 | Handler().LogError(this, "socket option not available", 0, "SO_RCVBUF", LOG_LEVEL_INFO); |
---|
1646 | #endif |
---|
1647 | return value; |
---|
1648 | } |
---|
1649 | |
---|
1650 | |
---|
1651 | #ifdef SO_RCVBUFFORCE |
---|
1652 | bool Socket::SetSoRcvbufforce(int x) |
---|
1653 | { |
---|
1654 | if (setsockopt(GetSocket(), SOL_SOCKET, SO_RCVBUFFORCE, (char *)&x, sizeof(x)) == -1) |
---|
1655 | { |
---|
1656 | Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_RCVBUFFORCE)", Errno, StrError(Errno), LOG_LEVEL_FATAL); |
---|
1657 | return false; |
---|
1658 | } |
---|
1659 | return true; |
---|
1660 | } |
---|
1661 | #endif |
---|
1662 | |
---|
1663 | |
---|
1664 | bool Socket::SetSoSndbuf(int x) |
---|
1665 | { |
---|
1666 | #ifdef SO_SNDBUF |
---|
1667 | if (setsockopt(GetSocket(), SOL_SOCKET, SO_SNDBUF, (char *)&x, sizeof(x)) == -1) |
---|
1668 | { |
---|
1669 | Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_SNDBUF)", Errno, StrError(Errno), LOG_LEVEL_FATAL); |
---|
1670 | return false; |
---|
1671 | } |
---|
1672 | return true; |
---|
1673 | #else |
---|
1674 | Handler().LogError(this, "socket option not available", 0, "SO_SNDBUF", LOG_LEVEL_INFO); |
---|
1675 | return false; |
---|
1676 | #endif |
---|
1677 | } |
---|
1678 | |
---|
1679 | |
---|
1680 | int Socket::SoSndbuf() |
---|
1681 | { |
---|
1682 | int value = 0; |
---|
1683 | #ifdef SO_SNDBUF |
---|
1684 | socklen_t len = sizeof(value); |
---|
1685 | if (getsockopt(GetSocket(), SOL_SOCKET, SO_SNDBUF, (char *)&value, &len) == -1) |
---|
1686 | { |
---|
1687 | Handler().LogError(this, "getsockopt(SOL_SOCKET, SO_SNDBUF)", Errno, StrError(Errno), LOG_LEVEL_FATAL); |
---|
1688 | } |
---|
1689 | #else |
---|
1690 | Handler().LogError(this, "socket option not available", 0, "SO_SNDBUF", LOG_LEVEL_INFO); |
---|
1691 | #endif |
---|
1692 | return value; |
---|
1693 | } |
---|
1694 | |
---|
1695 | |
---|
1696 | #ifdef SO_SNDBUFFORCE |
---|
1697 | bool Socket::SetSoSndbufforce(int x) |
---|
1698 | { |
---|
1699 | if (setsockopt(GetSocket(), SOL_SOCKET, SO_SNDBUFFORCE, (char *)&x, sizeof(x)) == -1) |
---|
1700 | { |
---|
1701 | Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_SNDBUFFORCE)", Errno, StrError(Errno), LOG_LEVEL_FATAL); |
---|
1702 | return false; |
---|
1703 | } |
---|
1704 | return true; |
---|
1705 | } |
---|
1706 | #endif |
---|
1707 | |
---|
1708 | |
---|
1709 | #ifdef SO_TIMESTAMP |
---|
1710 | bool Socket::SetSoTimestamp(bool x) |
---|
1711 | { |
---|
1712 | int optval = x ? 1 : 0; |
---|
1713 | if (setsockopt(GetSocket(), SOL_SOCKET, SO_TIMESTAMP, (char *)&optval, sizeof(optval)) == -1) |
---|
1714 | { |
---|
1715 | Handler().LogError(this, "setsockopt(SOL_SOCKET, SO_TIMESTAMP)", Errno, StrError(Errno), LOG_LEVEL_FATAL); |
---|
1716 | return false; |
---|
1717 | } |
---|
1718 | return true; |
---|
1719 | } |
---|
1720 | #endif |
---|
1721 | |
---|
1722 | |
---|
1723 | int Socket::SoType() |
---|
1724 | { |
---|
1725 | int value = 0; |
---|
1726 | #ifdef SO_TYPE |
---|
1727 | socklen_t len = sizeof(value); |
---|
1728 | if (getsockopt(GetSocket(), SOL_SOCKET, SO_TYPE, (char *)&value, &len) == -1) |
---|
1729 | { |
---|
1730 | Handler().LogError(this, "getsockopt(SOL_SOCKET, SO_TYPE)", Errno, StrError(Errno), LOG_LEVEL_FATAL); |
---|
1731 | } |
---|
1732 | #else |
---|
1733 | Handler().LogError(this, "socket option not available", 0, "SO_TYPE", LOG_LEVEL_INFO); |
---|
1734 | #endif |
---|
1735 | return value; |
---|
1736 | } |
---|
1737 | |
---|
1738 | |
---|
1739 | #ifdef ENABLE_TRIGGERS |
---|
1740 | void Socket::Subscribe(int id) |
---|
1741 | { |
---|
1742 | Handler().Subscribe(id, this); |
---|
1743 | } |
---|
1744 | |
---|
1745 | |
---|
1746 | void Socket::Unsubscribe(int id) |
---|
1747 | { |
---|
1748 | Handler().Unsubscribe(id, this); |
---|
1749 | } |
---|
1750 | |
---|
1751 | |
---|
1752 | void Socket::OnTrigger(int, const TriggerData&) |
---|
1753 | { |
---|
1754 | } |
---|
1755 | |
---|
1756 | |
---|
1757 | void Socket::OnCancelled(int) |
---|
1758 | { |
---|
1759 | } |
---|
1760 | #endif |
---|
1761 | |
---|
1762 | |
---|
1763 | void Socket::SetTimeout(time_t secs) |
---|
1764 | { |
---|
1765 | if (!secs) |
---|
1766 | { |
---|
1767 | Handler().AddList(m_socket, LIST_TIMEOUT, false); |
---|
1768 | return; |
---|
1769 | } |
---|
1770 | Handler().AddList(m_socket, LIST_TIMEOUT, true); |
---|
1771 | m_timeout_start = time(NULL); |
---|
1772 | m_timeout_limit = secs; |
---|
1773 | } |
---|
1774 | |
---|
1775 | |
---|
1776 | void Socket::OnTimeout() |
---|
1777 | { |
---|
1778 | } |
---|
1779 | |
---|
1780 | |
---|
1781 | void Socket::OnConnectTimeout() |
---|
1782 | { |
---|
1783 | } |
---|
1784 | |
---|
1785 | |
---|
1786 | bool Socket::Timeout(time_t tnow) |
---|
1787 | { |
---|
1788 | if (tnow - m_timeout_start > m_timeout_limit) |
---|
1789 | return true; |
---|
1790 | return false; |
---|
1791 | } |
---|
1792 | |
---|
1793 | |
---|
1794 | /** Returns local port number for bound socket file descriptor. */ |
---|
1795 | port_t Socket::GetSockPort() |
---|
1796 | { |
---|
1797 | #ifdef ENABLE_IPV6 |
---|
1798 | #ifdef IPPROTO_IPV6 |
---|
1799 | if (IsIpv6()) |
---|
1800 | { |
---|
1801 | struct sockaddr_in6 sa; |
---|
1802 | socklen_t sockaddr_length = sizeof(struct sockaddr_in6); |
---|
1803 | if (getsockname(GetSocket(), (struct sockaddr *)&sa, (socklen_t*)&sockaddr_length) == -1) |
---|
1804 | memset(&sa, 0, sizeof(sa)); |
---|
1805 | return ntohs(sa.sin6_port); |
---|
1806 | } |
---|
1807 | #endif |
---|
1808 | #endif |
---|
1809 | struct sockaddr_in sa; |
---|
1810 | socklen_t sockaddr_length = sizeof(struct sockaddr_in); |
---|
1811 | if (getsockname(GetSocket(), (struct sockaddr *)&sa, (socklen_t*)&sockaddr_length) == -1) |
---|
1812 | memset(&sa, 0, sizeof(sa)); |
---|
1813 | return ntohs(sa.sin_port); |
---|
1814 | } |
---|
1815 | |
---|
1816 | |
---|
1817 | /** Returns local ipv4 address for bound socket file descriptor. */ |
---|
1818 | ipaddr_t Socket::GetSockIP4() |
---|
1819 | { |
---|
1820 | #ifdef ENABLE_IPV6 |
---|
1821 | #ifdef IPPROTO_IPV6 |
---|
1822 | if (IsIpv6()) |
---|
1823 | { |
---|
1824 | return 0; |
---|
1825 | } |
---|
1826 | #endif |
---|
1827 | #endif |
---|
1828 | struct sockaddr_in sa; |
---|
1829 | socklen_t sockaddr_length = sizeof(struct sockaddr_in); |
---|
1830 | if (getsockname(GetSocket(), (struct sockaddr *)&sa, (socklen_t*)&sockaddr_length) == -1) |
---|
1831 | memset(&sa, 0, sizeof(sa)); |
---|
1832 | ipaddr_t a; |
---|
1833 | memcpy(&a, &sa.sin_addr, 4); |
---|
1834 | return a; |
---|
1835 | } |
---|
1836 | |
---|
1837 | |
---|
1838 | /** Returns local ipv4 address as text for bound socket file descriptor. */ |
---|
1839 | std::string Socket::GetSockAddress() |
---|
1840 | { |
---|
1841 | #ifdef ENABLE_IPV6 |
---|
1842 | #ifdef IPPROTO_IPV6 |
---|
1843 | if (IsIpv6()) |
---|
1844 | { |
---|
1845 | return ""; |
---|
1846 | } |
---|
1847 | #endif |
---|
1848 | #endif |
---|
1849 | struct sockaddr_in sa; |
---|
1850 | socklen_t sockaddr_length = sizeof(struct sockaddr_in); |
---|
1851 | if (getsockname(GetSocket(), (struct sockaddr *)&sa, (socklen_t*)&sockaddr_length) == -1) |
---|
1852 | memset(&sa, 0, sizeof(sa)); |
---|
1853 | Ipv4Address addr( sa ); |
---|
1854 | return addr.Convert(); |
---|
1855 | } |
---|
1856 | |
---|
1857 | |
---|
1858 | #ifdef ENABLE_IPV6 |
---|
1859 | #ifdef IPPROTO_IPV6 |
---|
1860 | /** Returns local ipv6 address for bound socket file descriptor. */ |
---|
1861 | struct in6_addr Socket::GetSockIP6() |
---|
1862 | { |
---|
1863 | if (IsIpv6()) |
---|
1864 | { |
---|
1865 | struct sockaddr_in6 sa; |
---|
1866 | socklen_t sockaddr_length = sizeof(struct sockaddr_in6); |
---|
1867 | if (getsockname(GetSocket(), (struct sockaddr *)&sa, (socklen_t*)&sockaddr_length) == -1) |
---|
1868 | memset(&sa, 0, sizeof(sa)); |
---|
1869 | return sa.sin6_addr; |
---|
1870 | } |
---|
1871 | struct in6_addr a; |
---|
1872 | memset(&a, 0, sizeof(a)); |
---|
1873 | return a; |
---|
1874 | } |
---|
1875 | |
---|
1876 | |
---|
1877 | /** Returns local ipv6 address as text for bound socket file descriptor. */ |
---|
1878 | std::string Socket::GetSockAddress6() |
---|
1879 | { |
---|
1880 | if (IsIpv6()) |
---|
1881 | { |
---|
1882 | struct sockaddr_in6 sa; |
---|
1883 | socklen_t sockaddr_length = sizeof(struct sockaddr_in6); |
---|
1884 | if (getsockname(GetSocket(), (struct sockaddr *)&sa, (socklen_t*)&sockaddr_length) == -1) |
---|
1885 | memset(&sa, 0, sizeof(sa)); |
---|
1886 | Ipv6Address addr( sa ); |
---|
1887 | return addr.Convert(); |
---|
1888 | } |
---|
1889 | return ""; |
---|
1890 | } |
---|
1891 | #endif |
---|
1892 | #endif |
---|
1893 | |
---|
1894 | |
---|
1895 | #ifdef SOCKETS_NAMESPACE |
---|
1896 | } |
---|
1897 | #endif |
---|
1898 | |
---|