1 /**
2 * Socket.cpp
3 * This file is part of the YATE Project http://YATE.null.ro
4 *
5 * Yet Another Telephony Engine - a fully featured software PBX and IVR
6 * Copyright (C) 2004-2014 Null Team
7 *
8 * This software is distributed under multiple licenses;
9 * see the COPYING file in the main directory for licensing
10 * information for this specific distribution.
11 *
12 * This use of this software may be subject to additional restrictions.
13 * See the LEGAL file in the main directory for details.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
18 */
19
20 #ifdef FDSIZE_HACK
21 #include <features.h>
22 #if (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2)
23 #include <bits/types.h>
24 #undef __FD_SETSIZE
25 #define __FD_SETSIZE FDSIZE_HACK
26 #else
27 #error Cannot set FD_SETSIZE on this platform - please ./configure --without-fdsize and hope it works
28 #endif
29 #endif
30
31 #include "yateclass.h"
32
33 #include <string.h>
34
35 #ifdef HAVE_POLL
36 #include <poll.h>
37 #ifndef POLLRDHUP
38 #define POLLRDHUP 0
39 #endif
40 #endif
41
42 #undef HAS_AF_UNIX
43
44 #ifndef _WINDOWS
45
46 #include <net/if.h>
47 #include <dirent.h>
48 #include <sys/stat.h>
49 #include <sys/un.h>
50 #define HAS_AF_UNIX
51 #ifndef UNIX_PATH_MAX
52 #define UNIX_PATH_MAX (sizeof(((struct sockaddr_un *)0)->sun_path))
53 #endif
54
55 #include <fcntl.h>
56 #include <stdlib.h>
57 #include <stdio.h>
58 #include <utime.h>
59 #endif
60
61 #ifndef SHUT_RD
62 #define SHUT_RD 0
63 #endif
64
65 #ifndef SHUT_WR
66 #define SHUT_WR 1
67 #endif
68
69 #ifndef SHUT_RDWR
70 #define SHUT_RDWR 2
71 #endif
72
73 #define MAX_SOCKLEN 1024
74 #define MAX_RESWAIT 5000000
75
76 using namespace TelEngine;
77
78 static Mutex s_mutex(false,"SocketAddr");
79
80 static const TokenDict s_tosValues[] = {
81 // TOS
82 { "normal", Socket::Normal },
83 { "lowdelay", Socket::LowDelay },
84 { "throughput", Socket::MaxThroughput },
85 { "reliability", Socket::MaxReliability },
86 { "mincost", Socket::MinCost },
87 // DSCP
88 { "expedited", Socket::ExpeditedFwd },
89 { "voice", Socket::VoiceAdmit },
90 { "af11", Socket::AF11 },
91 { "af12", Socket::AF12 },
92 { "af13", Socket::AF13 },
93 { "af21", Socket::AF21 },
94 { "af22", Socket::AF22 },
95 { "af23", Socket::AF23 },
96 { "af31", Socket::AF31 },
97 { "af32", Socket::AF32 },
98 { "af33", Socket::AF33 },
99 { "af41", Socket::AF41 },
100 { "af42", Socket::AF42 },
101 { "af43", Socket::AF43 },
102 { "cs0", Socket::CS0 },
103 { "cs1", Socket::CS1 },
104 { "cs2", Socket::CS2 },
105 { "cs3", Socket::CS3 },
106 { "cs4", Socket::CS4 },
107 { "cs5", Socket::CS5 },
108 { "cs6", Socket::CS6 },
109 { "cs7", Socket::CS7 },
110 { 0, 0 }
111 };
112
113 #ifdef _WINDOWS
114
115 // The number of seconds from January 1, 1601 (Windows FILETIME)
116 // to EPOCH January 1, 1970
117 #define FILETIME_EPOCH_SEC 11644473600
118
119 // Convert from FILETIME (100 nsec units since January 1, 1601)
120 // to time_t (seconds since January 1, 1970)
ftToEpoch(FILETIME & ft)121 static inline unsigned int ftToEpoch(FILETIME& ft)
122 {
123 // FILETIME in seconds
124 u_int64_t rval = ((ULARGE_INTEGER*)&ft)->QuadPart / 10000000;
125 // EPOCH time in seconds
126 rval -= FILETIME_EPOCH_SEC;
127 return (unsigned int)rval;
128 }
129
130 // Convert from time_t (seconds since January 1, 1970)
131 // to FILETIME (100 nsec units since January 1, 1601)
epochToFt(unsigned int secEpoch,FILETIME & ft)132 static void epochToFt(unsigned int secEpoch, FILETIME& ft)
133 {
134 u_int64_t time = (secEpoch + FILETIME_EPOCH_SEC) * 10000000;
135 ft.dwLowDateTime = (DWORD)time;
136 ft.dwHighDateTime = (DWORD)(time >> 32);
137 }
138
139 #endif
140
141
142 //
143 // IPv6 module functions
144 //
145 #ifdef AF_INET6
146
147 #if defined(HAVE_GHBN2_R) || defined(HAVE_GHBN2)
148 #define YATE_SOCKET_GHBN2_AVAILABLE
149
ghbn2Set(struct sockaddr * addr,hostent * he,int family)150 static inline bool ghbn2Set(struct sockaddr* addr, hostent* he, int family)
151 {
152 if (!(he && he->h_addrtype == family && he->h_addr_list))
153 return false;
154 char* val = he->h_addr_list[0];
155 if (!val)
156 return false;
157 if (family == AF_INET6) {
158 ((struct sockaddr_in6*)addr)->sin6_addr = *(in6_addr*)val;
159 return true;
160 }
161 return false;
162 }
163
164 // Resolve an address using gethostbyname2_r or gethostbyname2
165 // Return 1 on success, 0 on failure, -1 if not available
resolveGHBN2(struct sockaddr * addr,const char * name)166 static int resolveGHBN2(struct sockaddr* addr, const char* name)
167 {
168 if (!addr || TelEngine::null(name))
169 return 0;
170 int family = AF_INET6;
171 #ifdef HAVE_GHBN2_R
172 char buf[576];
173 struct hostent h;
174 struct hostent* hr = 0;
175 int errn = 0;
176 int r = gethostbyname2_r(name,family,&h,buf,sizeof(buf),&hr,&errn);
177 if (r != ERANGE) {
178 if (!r && ghbn2Set(addr,hr,family))
179 return 1;
180 return 0;
181 }
182 // Buffer too short: fallback to gethostbyname2 if available
183 #endif
184 #ifdef HAVE_GHBN2
185 Lock lck(s_mutex,MAX_RESWAIT);
186 if (lck.locked()) {
187 if (ghbn2Set(addr,gethostbyname2(name,family),family))
188 return 1;
189 }
190 else
191 Alarm("engine","socket",DebugWarn,"Resolver was busy, failing '%s'",name);
192 #else
193 #ifndef HAVE_GHBN2_R
194 return -1;
195 #endif
196 #endif
197 return 0;
198 }
199
200 #endif // defined(HAVE_GHBN2_R) || defined(HAVE_GHBN2)
201
202 // Resolve a domain to IPv6 address
resolveIPv6(struct sockaddr * addr,const char * name)203 static inline bool resolveIPv6(struct sockaddr* addr, const char* name)
204 {
205 static bool s_noIPv6 = true;
206 #ifdef YATE_SOCKET_GHBN2_AVAILABLE
207 int res = resolveGHBN2(addr,name);
208 if (res >= 0)
209 return res > 0;
210 #endif
211 // TODO: implement AF_INET6 resolving
212 if (s_noIPv6) {
213 s_noIPv6 = false;
214 Alarm("engine","socket",DebugWarn,"Resolver for %s is not available",
215 SocketAddr::lookupFamily(SocketAddr::IPv6));
216 }
217 return false;
218 }
219
220 #endif // AF_INET6
221
222
223 const String s_ipv4NullAddr = "0.0.0.0";
224 const String s_ipv6NullAddr = "::";
225
226 const TokenDict SocketAddr::s_familyName[] = {
227 {"Unknown", Unknown},
228 {"IPv4", IPv4},
229 {"IPv6", IPv6},
230 {"Unix", Unix},
231 {0,0},
232 };
233
SocketAddr(const struct sockaddr * addr,socklen_t len)234 SocketAddr::SocketAddr(const struct sockaddr* addr, socklen_t len)
235 : m_address(0), m_length(0)
236 {
237 assign(addr,len);
238 }
239
SocketAddr(int family,const void * raw)240 SocketAddr::SocketAddr(int family, const void* raw)
241 : m_address(0), m_length(0)
242 {
243 assign(family);
244 if (raw && m_address) {
245 switch (family) {
246 case AF_INET:
247 ::memcpy(&((struct sockaddr_in*)m_address)->sin_addr,raw,4);
248 break;
249 #ifdef AF_INET6
250 case AF_INET6:
251 ::memcpy(&((struct sockaddr_in6*)m_address)->sin6_addr,raw,16);
252 break;
253 #endif
254 }
255 SocketAddr::stringify();
256 }
257 }
258
~SocketAddr()259 SocketAddr::~SocketAddr()
260 {
261 clear();
262 }
263
clear()264 void SocketAddr::clear()
265 {
266 m_length = 0;
267 m_host.clear();
268 m_addr.clear();
269 void* tmp = m_address;
270 m_address = 0;
271 if (tmp)
272 ::free(tmp);
273 }
274
assign(int family)275 bool SocketAddr::assign(int family)
276 {
277 clear();
278 switch (family) {
279 case AF_INET:
280 m_length = sizeof(struct sockaddr_in);
281 break;
282 #ifdef AF_INET6
283 case AF_INET6:
284 m_length = sizeof(struct sockaddr_in6);
285 break;
286 #endif
287 #ifdef HAS_AF_UNIX
288 case AF_UNIX:
289 m_length = sizeof(struct sockaddr_un);
290 break;
291 #endif
292 }
293 if (m_length)
294 m_address = (struct sockaddr*) ::calloc(m_length,1);
295 if (m_address) {
296 m_address->sa_family = family;
297 #ifdef HAVE_SOCKADDR_LEN
298 m_address->sa_len = m_length;
299 #endif
300 return true;
301 }
302 return false;
303 }
304
assign(const struct sockaddr * addr,socklen_t len)305 void SocketAddr::assign(const struct sockaddr* addr, socklen_t len)
306 {
307 if (addr == m_address)
308 return;
309 #ifdef HAVE_SOCKADDR_LEN
310 if (addr && !len)
311 len = addr->sa_len;
312 #endif
313 if (addr && !len) {
314 switch (addr->sa_family) {
315 case AF_INET:
316 len = sizeof(struct sockaddr_in);
317 break;
318 #ifdef AF_INET6
319 case AF_INET6:
320 len = sizeof(struct sockaddr_in6);
321 break;
322 #endif
323 #ifdef HAS_AF_UNIX
324 case AF_UNIX:
325 len = sizeof(struct sockaddr_un);
326 break;
327 #endif
328 }
329 }
330 if (addr && m_address && (len == m_length) && !::memcmp(addr,m_address,len))
331 return;
332 clear();
333 if (addr && (len >= (socklen_t)sizeof(struct sockaddr))) {
334 void* tmp = ::malloc(len);
335 ::memcpy(tmp,addr,len);
336 m_address = (struct sockaddr*)tmp;
337 m_length = len;
338 stringify();
339 }
340 }
341
assign(const DataBlock & addr)342 bool SocketAddr::assign(const DataBlock& addr)
343 {
344 clear();
345 switch (addr.length()) {
346 case 4:
347 if (assign(AF_INET)) {
348 ::memcpy(&((struct sockaddr_in*)m_address)->sin_addr,addr.data(),addr.length());
349 stringify();
350 return true;
351 }
352 break;
353 #ifdef AF_INET6
354 case 8: // IPv6 /64 prefix
355 case 16:
356 if (assign(AF_INET6)) {
357 ::memcpy(&((struct sockaddr_in6*)m_address)->sin6_addr,addr.data(),addr.length());
358 stringify();
359 return true;
360 }
361 break;
362 #endif
363 }
364 return false;
365 }
366
copyAddr(DataBlock & addr) const367 int SocketAddr::copyAddr(DataBlock& addr) const
368 {
369 if (!m_address)
370 return false;
371 switch (family()) {
372 case AF_INET:
373 addr.assign(&((struct sockaddr_in*)m_address)->sin_addr,4);
374 return IPv4;
375 #ifdef AF_INET6
376 case AF_INET6:
377 addr.assign(&((struct sockaddr_in6*)m_address)->sin6_addr,16);
378 return IPv6;
379 #endif
380 }
381 return Unknown;
382 }
383
local(const SocketAddr & remote)384 bool SocketAddr::local(const SocketAddr& remote)
385 {
386 if (!remote.valid())
387 return false;
388 SocketAddr tmp(remote);
389 if (!tmp.port())
390 tmp.port(16384);
391 Socket sock(tmp.family(),SOCK_DGRAM);
392 if (sock.valid() && sock.connect(tmp) && sock.getSockName(*this)) {
393 port(0);
394 return true;
395 }
396 return false;
397 }
398
host(const String & name)399 bool SocketAddr::host(const String& name)
400 {
401 if (name.null())
402 return false;
403 if (name == m_host)
404 return true;
405 if (!m_address) {
406 int f = family(name);
407 switch (f) {
408 case Unix:
409 #ifdef HAS_AF_UNIX
410 if (assign(AF_UNIX) && host(name))
411 return true;
412 #endif
413 break;
414 case Unknown:
415 // fall through to set IP host
416 case IPv6:
417 #ifdef AF_INET6
418 if (assign(AF_INET6) && host(name))
419 return true;
420 #endif
421 if (f == IPv6)
422 break;
423 // fall through to IPv4
424 case IPv4:
425 if (assign(AF_INET) && host(name))
426 return true;
427 break;
428 }
429 // Restore data
430 clear();
431 return false;
432 }
433 switch (family()) {
434 case AF_INET:
435 {
436 in_addr_t a = inet_addr(name);
437 if (a == INADDR_NONE) {
438 #ifdef HAVE_GHBN_R
439 char buf[576];
440 struct hostent h;
441 struct hostent* hr = 0;
442 int errn = 0;
443 int r = gethostbyname_r(name,&h,buf,sizeof(buf),&hr,&errn);
444 if (r != ERANGE) {
445 if ((r == 0) && hr && (hr->h_addrtype == AF_INET))
446 a = *((in_addr_t*)(hr->h_addr_list[0]));
447 }
448 else // fallback to single threaded version
449 #endif
450 if (s_mutex.lock(MAX_RESWAIT)) {
451 struct hostent* he = gethostbyname(name);
452 if (he && (he->h_addrtype == AF_INET))
453 a = *((in_addr_t*)(he->h_addr_list[0]));
454 s_mutex.unlock();
455 }
456 else
457 Alarm("engine","socket",DebugWarn,"Resolver was busy, failing '%s'",name.c_str());
458 }
459 if (a != INADDR_NONE) {
460 ((struct sockaddr_in*)m_address)->sin_addr.s_addr = a;
461 stringify();
462 return true;
463 }
464 }
465 break;
466 #ifdef AF_INET6
467 case AF_INET6:
468 if (name.find('%') >= 0) {
469 String tmp, iface;
470 splitIface(name,tmp,&iface);
471 if (!host(tmp))
472 return false;
473 if (iface)
474 #ifndef _WINDOWS
475 scopeId(if_nametoindex(iface));
476 #else
477 scopeId(iface.toInteger(0,0,0));
478 #endif
479 return true;
480 }
481 #ifdef HAVE_PTON
482 if (inet_pton(family(),name,&((struct sockaddr_in6*)m_address)->sin6_addr) > 0) {
483 stringify();
484 return true;
485 }
486 #endif
487 if (resolveIPv6(m_address,name)) {
488 stringify();
489 return true;
490 }
491 break;
492 #endif // AF_INET6
493 #ifdef HAS_AF_UNIX
494 case AF_UNIX:
495 if (name.length() >= (UNIX_PATH_MAX-1))
496 return false;
497 ::strcpy(((struct sockaddr_un*)m_address)->sun_path,name.c_str());
498 stringify();
499 return true;
500 #endif
501 }
502 return false;
503 }
504
505 // Retrieve the family of an address
family(const String & addr)506 int SocketAddr::family(const String& addr)
507 {
508 if (!addr)
509 return Unknown;
510 bool ipv6 = false;
511 for (unsigned int i = 0; i < addr.length(); i++) {
512 if (addr[i] == '/')
513 return Unix;
514 if (addr[i] == ':')
515 ipv6 = true;
516 }
517 if (ipv6)
518 return IPv6;
519 in_addr_t a = inet_addr(addr);
520 if (a != INADDR_NONE || addr == YSTRING("255.255.255.255"))
521 return IPv4;
522 return Unknown;
523 }
524
525 // Convert the host address to a String
stringify(String & s,struct sockaddr * addr)526 bool SocketAddr::stringify(String& s, struct sockaddr* addr)
527 {
528 if (!addr)
529 return false;
530 switch (addr->sa_family) {
531 case AF_INET:
532 #ifdef HAVE_NTOP
533 {
534 char buf[16];
535 buf[0] = '\0';
536 s = inet_ntop(addr->sa_family,&((struct sockaddr_in*)addr)->sin_addr,
537 buf,sizeof(buf));
538 }
539 #else
540 s_mutex.lock();
541 s = inet_ntoa(((struct sockaddr_in*)addr)->sin_addr);
542 s_mutex.unlock();
543 #endif
544 return true;
545 #ifdef AF_INET6
546 case AF_INET6:
547 #ifdef HAVE_NTOP
548 {
549 char buf[48];
550 buf[0] = '\0';
551 s = inet_ntop(addr->sa_family,&((struct sockaddr_in6*)addr)->sin6_addr,
552 buf,sizeof(buf));
553 }
554 return true;
555 #endif
556 break;
557 #endif // AF_INET6
558 #ifdef HAS_AF_UNIX
559 case AF_UNIX:
560 s = ((struct sockaddr_un*)addr)->sun_path;
561 return true;
562 #endif
563 }
564 return false;
565 }
566
567 // Copy a host address to a buffer
copyAddr(uint8_t * buf,struct sockaddr * addr)568 int SocketAddr::copyAddr(uint8_t* buf, struct sockaddr* addr)
569 {
570 if (!(buf && addr))
571 return Unknown;
572 switch (addr->sa_family) {
573 case AF_INET:
574 ::memcpy(buf,&((struct sockaddr_in*)addr)->sin_addr,4);
575 return IPv4;
576 #ifdef AF_INET6
577 case AF_INET6:
578 ::memcpy(buf,&((struct sockaddr_in6*)addr)->sin6_addr,16);
579 return IPv6;
580 #endif
581 }
582 return Unknown;
583 }
584
585 // Append an address to a buffer
appendAddr(String & buf,const String & addr,int family)586 String& SocketAddr::appendAddr(String& buf, const String& addr, int family)
587 {
588 if (!addr)
589 return buf;
590 // Address already starts with [
591 if (addr[0] == '[') {
592 buf << addr;
593 return buf;
594 }
595 if (family == Unknown) {
596 // Match ip::v6 or ::ffff:ip.v4 but not ip.v4:port
597 int col = addr.rfind(':');
598 if (col >= 0) {
599 int dot = addr.find('.');
600 if ((dot < 0) || (dot > col))
601 family = IPv6;
602 }
603 }
604 if (family != IPv6)
605 buf << addr;
606 else
607 buf << "[" << addr << "]";
608 return buf;
609 }
610
611 // Check if an address is empty or null
isNullAddr(const String & addr,int family)612 bool SocketAddr::isNullAddr(const String& addr, int family)
613 {
614 if (!addr)
615 return true;
616 switch (family) {
617 case IPv4:
618 return addr == s_ipv4NullAddr;
619 case IPv6:
620 return addr == s_ipv6NullAddr;
621 }
622 return addr == s_ipv4NullAddr || addr == s_ipv6NullAddr;
623 }
624
625 // Split an interface from address
626 // An interface may be present in addr after a percent char (e.g. fe80::23%eth0)
splitIface(const String & buf,String & addr,String * iface)627 void SocketAddr::splitIface(const String& buf, String& addr, String* iface)
628 {
629 if (!buf) {
630 addr.clear();
631 if (iface)
632 iface->clear();
633 return;
634 }
635 int pos = buf.find('%');
636 if (pos < 0) {
637 if (iface)
638 iface->clear();
639 addr = buf;
640 }
641 else {
642 if (iface)
643 *iface = buf.substr(pos + 1);
644 addr = buf.substr(0,pos);
645 }
646 }
647
648 // Split an address into ip/port
649 // Handle addr, addr:port, [addr], [addr]:port
split(const String & buf,String & addr,int & port,bool portPresent)650 void SocketAddr::split(const String& buf, String& addr, int& port, bool portPresent)
651 {
652 if (!buf) {
653 addr.clear();
654 return;
655 }
656 if (buf[0] == '[') {
657 int p = buf.find(']',1);
658 if (p >= 1) {
659 if (p < ((int)buf.length() - 1) && buf[p + 1] == ':')
660 port = buf.substr(p + 2).toInteger();
661 addr.assign(buf.c_str() + 1,p - 1);
662 return;
663 }
664 }
665 int p = buf.find(':');
666 if (p >= 0) {
667 // Check for a second ':': it may be an IPv6 address
668 // or we expect a port at the end of an IPv6 address
669 int p2 = buf.rfind(':');
670 if (p == p2 || portPresent) {
671 port = buf.substr(p2 + 1).toInteger();
672 addr.assign(buf.c_str(),p2);
673 }
674 else
675 addr = buf;
676 }
677 else
678 addr = buf;
679 }
680
ipv4NullAddr()681 const String& SocketAddr::ipv4NullAddr()
682 {
683 return s_ipv4NullAddr;
684 }
685
ipv6NullAddr()686 const String& SocketAddr::ipv6NullAddr()
687 {
688 return s_ipv6NullAddr;
689 }
690
dictFamilyName()691 const TokenDict* SocketAddr::dictFamilyName()
692 {
693 return s_familyName;
694 }
695
stringify()696 void SocketAddr::stringify()
697 {
698 m_host.clear();
699 m_addr.clear();
700 if (m_length && m_address)
701 stringify(m_host,m_address);
702 }
703
704 // Store host:port in m_addr
updateAddr() const705 void SocketAddr::updateAddr() const
706 {
707 m_addr.clear();
708 appendTo(m_addr,host(),port(),family());
709 }
710
port() const711 int SocketAddr::port() const
712 {
713 switch (family()) {
714 case AF_INET:
715 return ntohs(((struct sockaddr_in*)m_address)->sin_port);
716 #ifdef AF_INET6
717 case AF_INET6:
718 return ntohs(((struct sockaddr_in6*)m_address)->sin6_port);
719 #endif
720 }
721 return 0;
722 }
723
port(int newport)724 bool SocketAddr::port(int newport)
725 {
726 switch (family()) {
727 case AF_INET:
728 ((struct sockaddr_in*)m_address)->sin_port = ntohs(newport);
729 break;
730 #ifdef AF_INET6
731 case AF_INET6:
732 ((struct sockaddr_in6*)m_address)->sin6_port = ntohs(newport);
733 break;
734 #endif
735 #ifdef HAS_AF_UNIX
736 case AF_UNIX:
737 break;
738 #endif
739 default:
740 return false;
741 }
742 m_addr.clear();
743 return true;
744 }
745
operator ==(const SocketAddr & other) const746 bool SocketAddr::operator==(const SocketAddr& other) const
747 {
748 if (m_length != other.length())
749 return false;
750 if (m_address == other.address())
751 return true;
752 if (m_address && other.address())
753 return !::memcmp(m_address,other.address(),m_length);
754 return false;
755 }
756
supports(int family)757 bool SocketAddr::supports(int family)
758 {
759 switch (family) {
760 case AF_INET:
761 return true;
762 #ifdef AF_INET6
763 case AF_INET6:
764 return true;
765 #endif
766 #ifdef HAS_AF_UNIX
767 case AF_UNIX:
768 return true;
769 #endif
770 default:
771 return false;
772 }
773 }
774
775
SocketFilter()776 SocketFilter::SocketFilter()
777 : m_socket(0)
778 {
779 }
780
~SocketFilter()781 SocketFilter::~SocketFilter()
782 {
783 if (m_socket)
784 m_socket->removeFilter(this);
785 }
786
getObject(const String & name) const787 void* SocketFilter::getObject(const String& name) const
788 {
789 if (name == YATOM("SocketFilter"))
790 return const_cast<SocketFilter*>(this);
791 return GenObject::getObject(name);
792 }
793
timerTick(const Time & when)794 void SocketFilter::timerTick(const Time& when)
795 {
796 }
797
valid() const798 bool SocketFilter::valid() const
799 {
800 return m_socket && m_socket->valid();
801 }
802
803
~Stream()804 Stream::~Stream()
805 {
806 }
807
canRetry() const808 bool Stream::canRetry() const
809 {
810 return false;
811 }
812
inProgress() const813 bool Stream::inProgress() const
814 {
815 return false;
816 }
817
setBlocking(bool block)818 bool Stream::setBlocking(bool block)
819 {
820 return false;
821 }
822
length()823 int64_t Stream::length()
824 {
825 return 0;
826 }
827
seek(SeekPos pos,int64_t offset)828 int64_t Stream::seek(SeekPos pos, int64_t offset)
829 {
830 return -1;
831 }
832
writeData(const char * str)833 int Stream::writeData(const char* str)
834 {
835 if (null(str))
836 return 0;
837 int len = ::strlen(str);
838 return writeData(str,len);
839 }
840
allocPipe(Stream * & reader,Stream * & writer)841 bool Stream::allocPipe(Stream*& reader, Stream*& writer)
842 {
843 if (supportsPipes()) {
844 File* r = new File;
845 File* w = new File;
846 if (File::createPipe(*r,*w)) {
847 reader = r;
848 writer = w;
849 return true;
850 }
851 delete r;
852 delete w;
853 }
854 reader = writer = 0;
855 return false;
856 }
857
allocPair(Stream * & str1,Stream * & str2)858 bool Stream::allocPair(Stream*& str1, Stream*& str2)
859 {
860 if (supportsPairs()) {
861 Socket* s1 = new Socket;
862 Socket* s2 = new Socket;
863 if (Socket::createPair(*s1,*s2)) {
864 str1 = s1;
865 str2 = s2;
866 return true;
867 }
868 delete s1;
869 delete s2;
870 }
871 str1 = str2 = 0;
872 return false;
873 }
874
supportsPipes()875 bool Stream::supportsPipes()
876 {
877 return true;
878 }
879
supportsPairs()880 bool Stream::supportsPairs()
881 {
882 #ifdef _WINDOWS
883 return false;
884 #else
885 return true;
886 #endif
887 }
888
889
writeData(const void * buffer,int len)890 int MemoryStream::writeData(const void* buffer, int len)
891 {
892 if ((len < 0) || !buffer)
893 return -1;
894 if (!len)
895 return 0;
896 int ovr = m_data.length() - m_offset;
897 if (ovr < 0)
898 ovr = 0;
899 else if (ovr > len)
900 ovr = len;
901 if (ovr > 0) {
902 // overwrite part of the existing data
903 void* dest = m_data.data(m_offset,ovr);
904 if (!dest)
905 return -1;
906 ::memcpy(dest,buffer,ovr);
907 m_offset += ovr;
908 len -= ovr;
909 buffer = static_cast<const char*>(buffer) + ovr;
910 }
911 if (len > 0) {
912 DataBlock tmp(const_cast<void*>(buffer),len,false);
913 m_data += tmp;
914 m_offset += len;
915 tmp.clear(false);
916 }
917 return len + ovr;
918 }
919
readData(void * buffer,int len)920 int MemoryStream::readData(void* buffer, int len)
921 {
922 if ((len <= 0) || !buffer)
923 return -1;
924 if (len + m_offset > m_data.length())
925 len = m_data.length() - m_offset;
926 if (len <= 0)
927 return 0;
928 void* src = m_data.data(m_offset,len);
929 if (!src)
930 return -1;
931 ::memcpy(buffer,src,len);
932 m_offset += len;
933 return len;
934 }
935
seek(SeekPos pos,int64_t offset)936 int64_t MemoryStream::seek(SeekPos pos, int64_t offset)
937 {
938 switch (pos) {
939 case SeekBegin:
940 break;
941 case SeekEnd:
942 offset += length();
943 break;
944 case SeekCurrent:
945 offset += m_offset;
946 break;
947 }
948 if ((offset < 0) || (offset > length()))
949 return -1;
950 m_offset = offset;
951 return offset;
952 }
953
954
File()955 File::File()
956 : m_handle(invalidHandle())
957 {
958 DDebug(DebugAll,"File::File() [%p]",this);
959 }
960
File(HANDLE handle)961 File::File(HANDLE handle)
962 : m_handle(handle)
963 {
964 DDebug(DebugAll,"File::File(%d) [%p]",(int)handle,this);
965 }
966
~File()967 File::~File()
968 {
969 DDebug(DebugAll,"File::~File() handle=%d [%p]",(int)m_handle,this);
970 terminate();
971 }
972
valid() const973 bool File::valid() const
974 {
975 return (m_handle != invalidHandle());
976 }
977
terminate()978 bool File::terminate()
979 {
980 bool ret = true;
981 HANDLE tmp = m_handle;
982 if (tmp != invalidHandle()) {
983 DDebug(DebugAll,"File::terminate() handle=%d [%p]",(int)m_handle,this);
984 m_handle = invalidHandle();
985 #ifdef _WINDOWS
986 ret = CloseHandle(tmp) != 0;
987 #else
988 ret = !::close(tmp);
989 #endif
990 }
991 if (ret)
992 clearError();
993 else {
994 copyError();
995 // put back the handle, we may have another chance later
996 m_handle = tmp;
997 }
998 return ret;
999 }
1000
attach(HANDLE handle)1001 void File::attach(HANDLE handle)
1002 {
1003 DDebug(DebugAll,"File::attach(%d) [%p]",(int)handle,this);
1004 if (handle == m_handle)
1005 return;
1006 terminate();
1007 m_handle = handle;
1008 clearError();
1009 }
1010
detach()1011 HANDLE File::detach()
1012 {
1013 DDebug(DebugAll,"File::detach() handle=%d [%p]",(int)m_handle,this);
1014 HANDLE tmp = m_handle;
1015 m_handle = invalidHandle();
1016 clearError();
1017 return tmp;
1018 }
1019
invalidHandle()1020 HANDLE File::invalidHandle()
1021 {
1022 #ifdef _WINDOWS
1023 return INVALID_HANDLE_VALUE;
1024 #else
1025 return -1;
1026 #endif
1027 }
1028
copyError()1029 void File::copyError()
1030 {
1031 #ifdef _WINDOWS
1032 m_error = (int)GetLastError();
1033 #else
1034 m_error = errno;
1035 #endif
1036 }
1037
canRetry() const1038 bool File::canRetry() const
1039 {
1040 if (!valid())
1041 return false;
1042 if (!m_error)
1043 return true;
1044 return (m_error == EAGAIN) || (m_error == EINTR)
1045 #ifndef _WINDOWS
1046 || (m_error == EWOULDBLOCK)
1047 #endif
1048 ;
1049 }
1050
setBlocking(bool block)1051 bool File::setBlocking(bool block)
1052 {
1053 #ifdef _WINDOWS
1054 return false;
1055 #else
1056 unsigned long flags = 1;
1057 flags = ::fcntl(m_handle,F_GETFL);
1058 if ((signed long)flags < 0) {
1059 copyError();
1060 return false;
1061 }
1062 if (block)
1063 flags &= !O_NONBLOCK;
1064 else
1065 flags |= O_NONBLOCK;
1066 if (::fcntl(m_handle,F_SETFL,flags) < 0) {
1067 copyError();
1068 return false;
1069 }
1070 clearError();
1071 return true;
1072 #endif
1073 }
1074
openPath(const char * name,bool canWrite,bool canRead,bool create,bool append,bool binary,bool pubReadable,bool pubWritable)1075 bool File::openPath(const char* name, bool canWrite, bool canRead,
1076 bool create, bool append, bool binary, bool pubReadable, bool pubWritable)
1077 {
1078 if (!terminate())
1079 return false;
1080 if (null(name) || !(canWrite || canRead))
1081 return false;
1082 #ifdef _WINDOWS
1083 DWORD access = 0;
1084 if (canWrite)
1085 access |= GENERIC_WRITE;
1086 if (canRead)
1087 access |= GENERIC_READ;
1088 DWORD createMode;
1089 if (create)
1090 createMode = (!canRead && !append) ? CREATE_ALWAYS : OPEN_ALWAYS;
1091 else
1092 createMode = OPEN_EXISTING;
1093 DWORD share = 0;
1094 if (!canWrite && canRead)
1095 share |= FILE_SHARE_READ;
1096 HANDLE h = CreateFile(name,access,share,NULL,createMode,FILE_ATTRIBUTE_NORMAL,NULL);
1097 if (h == invalidHandle()) {
1098 copyError();
1099 return false;
1100 }
1101 // Move file pointer if append. Result might be the same as the error code
1102 if (append &&
1103 ::SetFilePointer(h,0,NULL,FILE_END) == INVALID_SET_FILE_POINTER &&
1104 ::GetLastError() != NO_ERROR) {
1105 copyError();
1106 ::CloseHandle(h);
1107 return false;
1108 }
1109 #else
1110 int flags = O_LARGEFILE;
1111 if (canWrite)
1112 flags |= canRead ? O_RDWR : O_WRONLY;
1113 else if (canRead)
1114 flags = O_RDONLY;
1115 if (create)
1116 flags |= O_CREAT;
1117 if (append)
1118 flags |= O_APPEND;
1119 else if (!canRead)
1120 flags |= O_TRUNC;
1121 if (binary)
1122 flags |= O_BINARY;
1123 int mode = S_IRUSR|S_IWUSR;
1124 if (pubReadable)
1125 mode |= S_IRGRP|S_IROTH;
1126 if (pubWritable)
1127 mode |= S_IWGRP|S_IWOTH;
1128 HANDLE h = ::open(name,flags,mode);
1129 if (h == invalidHandle()) {
1130 copyError();
1131 return false;
1132 }
1133 #endif
1134 attach(h);
1135 clearError();
1136 return true;
1137 }
1138
length()1139 int64_t File::length()
1140 {
1141 if (!valid())
1142 return 0;
1143 #ifdef _WINDOWS
1144 LARGE_INTEGER li;
1145 li.LowPart = ::GetFileSize(m_handle,(LPDWORD)(&li.HighPart));
1146 if (li.LowPart == INVALID_FILE_SIZE && ::GetLastError() != NO_ERROR) {
1147 copyError();
1148 return -1;
1149 }
1150 return li.QuadPart;
1151 #else
1152 int64_t pos = seek(SeekCurrent);
1153 if (pos < 0) {
1154 copyError();
1155 return 0;
1156 }
1157 int64_t len = seek(SeekEnd);
1158 seek(SeekBegin,pos);
1159 return len;
1160 #endif
1161 }
1162
1163 // Set the file read/write pointer
seek(SeekPos pos,int64_t offset)1164 int64_t File::seek(SeekPos pos, int64_t offset)
1165 {
1166 if (!valid())
1167 return -1;
1168 #ifdef _WINDOWS
1169 int whence = (pos == SeekBegin) ? FILE_BEGIN : ((pos == SeekEnd) ? FILE_END : FILE_CURRENT);
1170 LARGE_INTEGER li;
1171 li.QuadPart = offset;
1172 li.LowPart = ::SetFilePointer(m_handle,li.LowPart,&li.HighPart,whence);
1173 // Check low 32bit value and the last error
1174 // It might have the same as the error code
1175 if (li.LowPart == INVALID_SET_FILE_POINTER && ::GetLastError() != NO_ERROR) {
1176 copyError();
1177 return -1;
1178 }
1179 return li.QuadPart;
1180 #else
1181 int whence = (pos == SeekBegin) ? SEEK_SET : ((pos == SeekEnd) ? SEEK_END : SEEK_CUR);
1182 off_t p = ::lseek(m_handle,(off_t)offset,whence);
1183 if (p == (off_t)-1) {
1184 copyError();
1185 return -1;
1186 }
1187 return (int64_t)p;
1188 #endif
1189 }
1190
writeData(const void * buffer,int length)1191 int File::writeData(const void* buffer, int length)
1192 {
1193 if (!buffer)
1194 length = 0;
1195 #ifdef _WINDOWS
1196 DWORD nbytes = 0;
1197 if (WriteFile(m_handle,buffer,length,&nbytes,0)) {
1198 clearError();
1199 return nbytes;
1200 }
1201 copyError();
1202 return -1;
1203 #else
1204 int res = ::write(m_handle,buffer,length);
1205 if (res >= 0)
1206 clearError();
1207 else
1208 copyError();
1209 return res;
1210 #endif
1211 }
1212
readData(void * buffer,int length)1213 int File::readData(void* buffer, int length)
1214 {
1215 if (!buffer)
1216 length = 0;
1217 #ifdef _WINDOWS
1218 DWORD nbytes = 0;
1219 if (ReadFile(m_handle,buffer,length,&nbytes,0)) {
1220 clearError();
1221 return nbytes;
1222 }
1223 else if (::GetLastError() == ERROR_HANDLE_EOF) {
1224 clearError();
1225 return 0;
1226 }
1227 copyError();
1228 return -1;
1229 #else
1230 int res = ::read(m_handle,buffer,length);
1231 if (res >= 0)
1232 clearError();
1233 else
1234 copyError();
1235 return res;
1236 #endif
1237 }
1238
createPipe(File & reader,File & writer)1239 bool File::createPipe(File& reader, File& writer)
1240 {
1241 #ifdef _WINDOWS
1242 HANDLE rd, wr;
1243 SECURITY_ATTRIBUTES sa;
1244 sa.nLength = sizeof(sa);
1245 sa.lpSecurityDescriptor = NULL;
1246 sa.bInheritHandle = TRUE;
1247 if (::CreatePipe(&rd,&wr,&sa,0)) {
1248 reader.attach(rd);
1249 writer.attach(wr);
1250 return true;
1251 }
1252 #else
1253 HANDLE fifo[2];
1254 if (!::pipe(fifo)) {
1255 reader.attach(fifo[0]);
1256 writer.attach(fifo[1]);
1257 return true;
1258 }
1259 #endif
1260 return false;
1261 }
1262
1263 // Retrieve the file's modification time (the file must be already opened)
getFileTime(unsigned int & secEpoch)1264 bool File::getFileTime(unsigned int& secEpoch)
1265 {
1266 #ifdef _WINDOWS
1267 FILETIME ftWrite;
1268 if (::GetFileTime(handle(),NULL,NULL,&ftWrite)) {
1269 clearError();
1270 secEpoch = ftToEpoch(ftWrite);
1271 return true;
1272 }
1273 #else
1274 struct stat st;
1275 if (0 == ::fstat(handle(),&st)) {
1276 clearError();
1277 secEpoch = st.st_mtime;
1278 return true;
1279 }
1280 #endif
1281 copyError();
1282 return false;
1283 }
1284
1285 // Build the MD5 hex digest of an opened file.
md5(String & buffer)1286 bool File::md5(String& buffer)
1287 {
1288 if (-1 == Stream::seek(0))
1289 return false;
1290 MD5 md5;
1291 unsigned char buf[65536];
1292 bool ok = false;
1293 unsigned int retry = 3;
1294 while (retry) {
1295 int n = readData(buf,sizeof(buf));
1296 if (n < 0) {
1297 if (canRetry())
1298 retry--;
1299 else
1300 retry = 0;
1301 continue;
1302 }
1303 if (n == 0) {
1304 ok = true;
1305 break;
1306 }
1307 DataBlock tmp(buf,n,false);
1308 md5 << tmp;
1309 tmp.clear(false);
1310 }
1311 if (ok)
1312 buffer = md5.hexDigest();
1313 else
1314 buffer = "";
1315 return ok;
1316 }
1317
1318
1319 // Set last error and return false
getLastError(int * error)1320 static inline bool getLastError(int* error)
1321 {
1322 if (error)
1323 *error = Thread::lastError();
1324 return false;
1325 }
1326
1327 // Check if a file name is non null
1328 // Set error and return false if it is
fileNameOk(const char * name,int * error)1329 static inline bool fileNameOk(const char* name, int* error)
1330 {
1331 if (!null(name))
1332 return true;
1333 if (error)
1334 #ifdef _WINDOWS
1335 *error = ERROR_INVALID_PARAMETER;
1336 #else
1337 *error = EINVAL;
1338 #endif
1339 return false;
1340 }
1341
1342 // Set a file's modification time
setFileTime(const char * name,unsigned int secEpoch,int * error)1343 bool File::setFileTime(const char* name, unsigned int secEpoch, int* error)
1344 {
1345 if (!fileNameOk(name,error))
1346 return false;
1347 #ifdef _WINDOWS
1348 File f;
1349 if (f.openPath(name,true)) {
1350 FILETIME ftWrite;
1351 epochToFt(secEpoch,ftWrite);
1352 bool ok = (0 != ::SetFileTime(f.handle(),NULL,NULL,&ftWrite));
1353 if (!ok && error)
1354 *error = ::GetLastError();
1355 f.terminate();
1356 return ok;
1357 }
1358 #else
1359 struct stat st;
1360 if (0 == ::stat(name,&st)) {
1361 struct utimbuf tb;
1362 tb.actime = st.st_atime;
1363 tb.modtime = secEpoch;
1364 if (0 == ::utime(name,&tb))
1365 return true;
1366 }
1367 #endif
1368 return getLastError(error);
1369 }
1370
1371 // Retrieve a file's modification time
getFileTime(const char * name,unsigned int & secEpoch,int * error)1372 bool File::getFileTime(const char* name, unsigned int& secEpoch, int* error)
1373 {
1374 if (!fileNameOk(name,error))
1375 return false;
1376 #ifdef _WINDOWS
1377 WIN32_FILE_ATTRIBUTE_DATA fa;
1378 if (::GetFileAttributesExA(name,GetFileExInfoStandard,&fa)) {
1379 secEpoch = ftToEpoch(fa.ftLastWriteTime);
1380 return true;
1381 }
1382 #else
1383 struct stat st;
1384 if (0 == ::stat(name,&st)) {
1385 secEpoch = st.st_mtime;
1386 return true;
1387 }
1388 #endif
1389 return getLastError(error);
1390 }
1391
1392 // Check if a file exists
exists(const char * name,int * error)1393 bool File::exists(const char* name, int* error)
1394 {
1395 if (!fileNameOk(name,error))
1396 return false;
1397 #ifdef _WINDOWS
1398 WIN32_FIND_DATA d;
1399 HANDLE h = ::FindFirstFile(name,&d);
1400 if (h != invalidHandle()) {
1401 ::FindClose(h);
1402 return true;
1403 }
1404 #else
1405 if (0 == ::access(name,F_OK))
1406 return true;
1407 #endif
1408 return getLastError(error);
1409 }
1410
1411 // Rename (move) a file (or directory) entry from the filesystem
rename(const char * oldFile,const char * newFile,int * error)1412 bool File::rename(const char* oldFile, const char* newFile, int* error)
1413 {
1414 if (!(fileNameOk(oldFile,error) && fileNameOk(newFile,error)))
1415 return false;
1416 #ifdef _WINDOWS
1417 DWORD flags = MOVEFILE_COPY_ALLOWED | // Allow moving file on another volume
1418 MOVEFILE_REPLACE_EXISTING | // Replace existing
1419 MOVEFILE_WRITE_THROUGH; // Don't return until copy/delete is performed
1420 if (::MoveFileExA(oldFile,newFile,flags))
1421 return true;
1422 #else
1423 if (0 == ::rename(oldFile,newFile))
1424 return true;
1425 #endif
1426 return getLastError(error);
1427 }
1428
remove(const char * name,int * error)1429 bool File::remove(const char* name, int* error)
1430 {
1431 if (!fileNameOk(name,error))
1432 return false;
1433 #ifdef _WINDOWS
1434 if (::DeleteFileA(name))
1435 return true;
1436 #else
1437 if (0 == ::unlink(name))
1438 return true;
1439 #endif
1440 return getLastError(error);
1441 }
1442
1443 // Build the MD5 hex digest of a file.
md5(const char * name,String & buffer,int * error)1444 bool File::md5(const char* name, String& buffer, int* error)
1445 {
1446 File f;
1447 bool ok = false;
1448 if (f.openPath(name,false,true) && f.md5(buffer))
1449 ok = true;
1450 else if (error)
1451 *error = f.error();
1452 f.terminate();
1453 return ok;
1454 }
1455
1456 // Create a folder (directory)
mkDir(const char * path,int * error,int mode)1457 bool File::mkDir(const char* path, int* error, int mode)
1458 {
1459 if (!fileNameOk(path,error))
1460 return false;
1461 #ifdef _WINDOWS
1462 if (::CreateDirectoryA(path,NULL))
1463 return true;
1464 #else
1465 if (0 == ::mkdir(path,(mode_t)mode))
1466 return true;
1467 #endif
1468 return getLastError(error);
1469 }
1470
1471 // Remove an empty folder (directory)
rmDir(const char * path,int * error)1472 bool File::rmDir(const char* path, int* error)
1473 {
1474 if (!fileNameOk(path,error))
1475 return false;
1476 #ifdef _WINDOWS
1477 if (::RemoveDirectoryA(path))
1478 return true;
1479 #else
1480 if (0 == ::rmdir(path))
1481 return true;
1482 #endif
1483 return getLastError(error);
1484 }
1485
1486 // Skip special directories (. or ..)
skipSpecial(const char * s)1487 static inline bool skipSpecial(const char* s)
1488 {
1489 return *s && *s == '.' && (!s[1] || (s[1] == '.' && !s[2]));
1490 }
1491
1492 // Enumerate a folder (directory) content
listDirectory(const char * path,ObjList * dirs,ObjList * files,int * error)1493 bool File::listDirectory(const char* path, ObjList* dirs, ObjList* files, int* error)
1494 {
1495 if (!(dirs || files))
1496 return true;
1497 if (!fileNameOk(path,error))
1498 return false;
1499 bool ok = false;
1500 #ifdef _WINDOWS
1501 String name(path);
1502 if (!name.endsWith("\\"))
1503 name << "\\";
1504 name << "*";
1505 // Init find
1506 WIN32_FIND_DATAA d;
1507 HANDLE hFind = ::FindFirstFileA(name,&d);
1508 if (hFind == INVALID_HANDLE_VALUE) {
1509 if (::GetLastError() == ERROR_NO_MORE_FILES)
1510 return true;
1511 return getLastError(error);
1512 }
1513 // Enumerate content
1514 ::SetLastError(0);
1515 do {
1516 if (d.dwFileAttributes & FILE_ATTRIBUTE_DEVICE ||
1517 skipSpecial(d.cFileName))
1518 continue;
1519 if (d.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
1520 if (dirs)
1521 dirs->append(new String(d.cFileName));
1522 }
1523 else if (files)
1524 files->append(new String(d.cFileName));
1525 }
1526 while (::FindNextFileA(hFind,&d));
1527 int code = ::GetLastError();
1528 ok = !code || code == ERROR_NO_MORE_FILES;
1529 // Get error before closing the handle to avoid having a wrong one
1530 if (!ok && error)
1531 *error = code;
1532 ::FindClose(hFind);
1533 #else
1534 errno = 0;
1535 DIR* dir = ::opendir(path);
1536 if (!dir) {
1537 if (!errno)
1538 return true;
1539 return getLastError(error);
1540 }
1541 struct dirent* entry;
1542 while ((entry = ::readdir(dir)) != 0) {
1543 if (skipSpecial(entry->d_name))
1544 continue;
1545 #ifdef _DIRENT_HAVE_D_TYPE
1546 if (entry->d_type == DT_DIR) {
1547 if (dirs)
1548 dirs->append(new String(entry->d_name));
1549 }
1550 else if (entry->d_type == DT_REG && files)
1551 files->append(new String(entry->d_name));
1552 #else
1553 struct stat stat_buf;
1554 String p;
1555 p << path << "/" << entry->d_name;
1556 if (::stat(p,&stat_buf))
1557 break;
1558 if (S_ISDIR(stat_buf.st_mode)) {
1559 if (dirs)
1560 dirs->append(new String(entry->d_name));
1561 }
1562 else if (S_ISREG(stat_buf.st_mode) && files)
1563 files->append(new String(entry->d_name));
1564 #endif // _DIRENT_HAVE_D_TYPE
1565 }
1566 ok = !errno;
1567 // Get error before closing DIR to avoid having a wrong one
1568 if (!ok && error)
1569 *error = errno;
1570 ::closedir(dir);
1571 #endif // _WINDOWS
1572 return ok;
1573 }
1574
1575
Socket()1576 Socket::Socket()
1577 : m_handle(invalidHandle())
1578 {
1579 DDebug(DebugAll,"Socket::Socket() [%p]",this);
1580 }
1581
Socket(SOCKET handle)1582 Socket::Socket(SOCKET handle)
1583 : m_handle(handle)
1584 {
1585 DDebug(DebugAll,"Socket::Socket(%d) [%p]",handle,this);
1586 }
1587
Socket(int domain,int type,int protocol)1588 Socket::Socket(int domain, int type, int protocol)
1589 : m_handle(invalidHandle())
1590 {
1591 DDebug(DebugAll,"Socket::Socket(%d,%d,%d) [%p]",domain,type,protocol,this);
1592 m_handle = ::socket(domain,type,protocol);
1593 if (!valid())
1594 copyError();
1595 }
1596
~Socket()1597 Socket::~Socket()
1598 {
1599 DDebug(DebugAll,"Socket::~Socket() handle=%d [%p]",m_handle,this);
1600 clearFilters();
1601 terminate();
1602 }
1603
valid() const1604 bool Socket::valid() const
1605 {
1606 return (m_handle != invalidHandle());
1607 }
1608
create(int domain,int type,int protocol)1609 bool Socket::create(int domain, int type, int protocol)
1610 {
1611 DDebug(DebugAll,"Socket::create(%d,%d,%d) [%p]",domain,type,protocol,this);
1612 terminate();
1613 m_handle = ::socket(domain,type,protocol);
1614 if (valid()) {
1615 clearError();
1616 return true;
1617 }
1618 else {
1619 copyError();
1620 return false;
1621 }
1622 }
1623
terminate()1624 bool Socket::terminate()
1625 {
1626 bool ret = true;
1627 SOCKET tmp = m_handle;
1628 if (tmp != invalidHandle()) {
1629 DDebug(DebugAll,"Socket::terminate() handle=%d [%p]",m_handle,this);
1630 m_handle = invalidHandle();
1631 #ifdef _WINDOWS
1632 ret = !::closesocket(tmp);
1633 #else
1634 ret = !::close(tmp);
1635 #endif
1636 }
1637 if (ret)
1638 clearError();
1639 else {
1640 copyError();
1641 // put back the handle, we may have another chance later
1642 m_handle = tmp;
1643 }
1644 return ret;
1645 }
1646
attach(SOCKET handle)1647 void Socket::attach(SOCKET handle)
1648 {
1649 DDebug(DebugAll,"Socket::attach(%d) [%p]",handle,this);
1650 if (handle == m_handle)
1651 return;
1652 terminate();
1653 m_handle = handle;
1654 clearError();
1655 }
1656
detach()1657 SOCKET Socket::detach()
1658 {
1659 DDebug(DebugAll,"Socket::detach() handle=%d [%p]",m_handle,this);
1660 SOCKET tmp = m_handle;
1661 m_handle = invalidHandle();
1662 clearError();
1663 return tmp;
1664 }
1665
invalidHandle()1666 SOCKET Socket::invalidHandle()
1667 {
1668 #ifdef _WINDOWS
1669 return INVALID_SOCKET;
1670 #else
1671 return -1;
1672 #endif
1673 }
1674
tosValues()1675 const TokenDict* Socket::tosValues()
1676 {
1677 return s_tosValues;
1678 }
1679
socketError()1680 int Socket::socketError()
1681 {
1682 #ifdef _WINDOWS
1683 return SOCKET_ERROR;
1684 #else
1685 return -1;
1686 #endif
1687 }
1688
copyError()1689 void Socket::copyError()
1690 {
1691 #ifdef _WINDOWS
1692 m_error = WSAGetLastError();
1693 #else
1694 m_error = errno;
1695 #endif
1696 }
1697
checkError(int retcode,bool strict)1698 bool Socket::checkError(int retcode, bool strict)
1699 {
1700 if (strict && (retcode != socketError()))
1701 retcode = 0;
1702 if (retcode) {
1703 copyError();
1704 return false;
1705 }
1706 else {
1707 clearError();
1708 return true;
1709 }
1710 }
1711
canRetry() const1712 bool Socket::canRetry() const
1713 {
1714 if (!valid())
1715 return false;
1716 if (!m_error)
1717 return true;
1718 return (m_error == EAGAIN) || (m_error == EINTR) ||
1719 #ifdef _WINDOWS
1720 (m_error == WSAEWOULDBLOCK);
1721 #else
1722 (m_error == EWOULDBLOCK);
1723 #endif
1724 }
1725
1726 // Check if the last error code indicates a non blocking operation in progress
inProgress() const1727 bool Socket::inProgress() const
1728 {
1729 if (!valid())
1730 return false;
1731 #ifdef _WINDOWS
1732 return m_error == WSAEWOULDBLOCK;
1733 #else
1734 return m_error == EINPROGRESS;
1735 #endif
1736 }
1737
canSelect() const1738 bool Socket::canSelect() const
1739 {
1740 return canSelect(m_handle);
1741 }
1742
bind(struct sockaddr * addr,socklen_t addrlen)1743 bool Socket::bind(struct sockaddr* addr, socklen_t addrlen)
1744 {
1745 return checkError(::bind(m_handle,addr,addrlen));
1746 }
1747
listen(unsigned int backlog)1748 bool Socket::listen(unsigned int backlog)
1749 {
1750 if ((backlog == 0) || (backlog > SOMAXCONN))
1751 backlog = SOMAXCONN;
1752 return checkError(::listen(m_handle,backlog));
1753 }
1754
accept(struct sockaddr * addr,socklen_t * addrlen)1755 Socket* Socket::accept(struct sockaddr* addr, socklen_t* addrlen)
1756 {
1757 SOCKET sock = acceptHandle(addr,addrlen);
1758 return (sock == invalidHandle()) ? 0 : new Socket(sock);
1759 }
1760
accept(SocketAddr & addr)1761 Socket* Socket::accept(SocketAddr& addr)
1762 {
1763 char buf[MAX_SOCKLEN];
1764 socklen_t len = sizeof(buf);
1765 Socket* sock = accept((struct sockaddr*)buf,&len);
1766 if (sock)
1767 addr.assign((struct sockaddr*)buf,len);
1768 return sock;
1769 }
1770
acceptHandle(struct sockaddr * addr,socklen_t * addrlen)1771 SOCKET Socket::acceptHandle(struct sockaddr* addr, socklen_t* addrlen)
1772 {
1773 if (addrlen && !addr)
1774 *addrlen = 0;
1775 SOCKET res = ::accept(m_handle,addr,addrlen);
1776 if (res == invalidHandle())
1777 copyError();
1778 else
1779 clearError();
1780 return res;
1781 }
1782
1783 // Update socket error from socket options
updateError()1784 bool Socket::updateError()
1785 {
1786 int error = 0;
1787 socklen_t len = sizeof(error);
1788 if (getOption(SOL_SOCKET,SO_ERROR,&error,&len)) {
1789 m_error = error;
1790 return true;
1791 }
1792 return false;
1793 }
1794
connect(struct sockaddr * addr,socklen_t addrlen)1795 bool Socket::connect(struct sockaddr* addr, socklen_t addrlen)
1796 {
1797 if (addrlen && !addr)
1798 addrlen = 0;
1799 return checkError(::connect(m_handle,addr,addrlen));
1800 }
1801
1802 // Asynchronously connects the socket to a remote address
connectAsync(struct sockaddr * addr,socklen_t addrlen,unsigned int toutUs,bool * timeout)1803 bool Socket::connectAsync(struct sockaddr* addr, socklen_t addrlen, unsigned int toutUs, bool* timeout)
1804 {
1805 if (!canSelect())
1806 return false;
1807 if (connect(addr,addrlen))
1808 return true;
1809 if (!inProgress())
1810 return false;
1811 unsigned int intervals = toutUs / Thread::idleUsec();
1812 // Make sure we wait for at least 1 timeout interval
1813 if (!intervals)
1814 intervals = 1;
1815 clearError();
1816 while (intervals) {
1817 bool done = false;
1818 bool event = false;
1819 if (!select(0,&done,&event,Thread::idleUsec()))
1820 return false;
1821 if (done || event) {
1822 updateError();
1823 return error() == 0;
1824 }
1825 if (Thread::check(false))
1826 return false;
1827 intervals--;
1828 }
1829 if (timeout)
1830 *timeout = true;
1831 return false;
1832 }
1833
shutdown(bool stopReads,bool stopWrites)1834 bool Socket::shutdown(bool stopReads, bool stopWrites)
1835 {
1836 int how;
1837 if (stopReads) {
1838 if (stopWrites)
1839 how = SHUT_RDWR;
1840 else
1841 how = SHUT_RD;
1842 }
1843 else {
1844 if (stopWrites)
1845 how = SHUT_WR;
1846 else
1847 // nothing to do - no error
1848 return true;
1849 }
1850 return checkError(::shutdown(m_handle,how));
1851 }
1852
getSockName(struct sockaddr * addr,socklen_t * addrlen)1853 bool Socket::getSockName(struct sockaddr* addr, socklen_t* addrlen)
1854 {
1855 if (addrlen && !addr)
1856 *addrlen = 0;
1857 return checkError(::getsockname(m_handle,addr,addrlen));
1858 }
1859
getSockName(SocketAddr & addr)1860 bool Socket::getSockName(SocketAddr& addr)
1861 {
1862 char buf[MAX_SOCKLEN];
1863 socklen_t len = sizeof(buf);
1864 bool ok = getSockName((struct sockaddr*)buf,&len);
1865 if (ok)
1866 addr.assign((struct sockaddr*)buf,len);
1867 return ok;
1868 }
1869
getPeerName(struct sockaddr * addr,socklen_t * addrlen)1870 bool Socket::getPeerName(struct sockaddr* addr, socklen_t* addrlen)
1871 {
1872 if (addrlen && !addr)
1873 *addrlen = 0;
1874 return checkError(::getpeername(m_handle,addr,addrlen));
1875 }
1876
getPeerName(SocketAddr & addr)1877 bool Socket::getPeerName(SocketAddr& addr)
1878 {
1879 char buf[MAX_SOCKLEN];
1880 socklen_t len = sizeof(buf);
1881 bool ok = getPeerName((struct sockaddr*)buf,&len);
1882 if (ok)
1883 addr.assign((struct sockaddr*)buf,len);
1884 return ok;
1885 }
1886
sendTo(const void * buffer,int length,const struct sockaddr * addr,socklen_t adrlen,int flags)1887 int Socket::sendTo(const void* buffer, int length, const struct sockaddr* addr, socklen_t adrlen, int flags)
1888 {
1889 if (!addr)
1890 return send(buffer,length,flags);
1891 if (!buffer)
1892 length = 0;
1893 int res = ::sendto(m_handle,(const char*)buffer,length,flags,addr,adrlen);
1894 checkError(res,true);
1895 return res;
1896 }
1897
send(const void * buffer,int length,int flags)1898 int Socket::send(const void* buffer, int length, int flags)
1899 {
1900 if (!buffer)
1901 length = 0;
1902 int res = ::send(m_handle,(const char*)buffer,length,flags);
1903 checkError(res,true);
1904 return res;
1905 }
1906
writeData(const void * buffer,int length)1907 int Socket::writeData(const void* buffer, int length)
1908 {
1909 #ifdef _WINDOWS
1910 return send(buffer,length);
1911 #else
1912 if (!buffer)
1913 length = 0;
1914 int res = ::write(m_handle,buffer,length);
1915 checkError(res,true);
1916 return res;
1917 #endif
1918 }
1919
recvFrom(void * buffer,int length,struct sockaddr * addr,socklen_t * adrlen,int flags)1920 int Socket::recvFrom(void* buffer, int length, struct sockaddr* addr, socklen_t* adrlen, int flags)
1921 {
1922 if (!buffer)
1923 length = 0;
1924 if (adrlen && !addr)
1925 *adrlen = 0;
1926 int res = ::recvfrom(m_handle,(char*)buffer,length,flags,addr,adrlen);
1927 if (checkError(res,true) && applyFilters(buffer,res,flags,addr,(adrlen ? *adrlen : 0))) {
1928 m_error = EAGAIN;
1929 res = socketError();
1930 }
1931 return res;
1932 }
1933
recvFrom(void * buffer,int length,SocketAddr & addr,int flags)1934 int Socket::recvFrom(void* buffer, int length, SocketAddr& addr, int flags)
1935 {
1936 char buf[MAX_SOCKLEN];
1937 socklen_t len = sizeof(buf);
1938 int res = recvFrom(buffer,length,(struct sockaddr*)buf,&len,flags);
1939 if (res != socketError())
1940 addr.assign((struct sockaddr*)buf,len);
1941 return res;
1942 }
1943
recv(void * buffer,int length,int flags)1944 int Socket::recv(void* buffer, int length, int flags)
1945 {
1946 if (!buffer)
1947 length = 0;
1948 int res = ::recv(m_handle,(char*)buffer,length,flags);
1949 if (checkError(res,true) && applyFilters(buffer,res,flags)) {
1950 m_error = EAGAIN;
1951 res = socketError();
1952 }
1953 return res;
1954 }
1955
readData(void * buffer,int length)1956 int Socket::readData(void* buffer, int length)
1957 {
1958 #ifdef _WINDOWS
1959 return recv(buffer,length);
1960 #else
1961 if (!buffer)
1962 length = 0;
1963 int res = ::read(m_handle,buffer,length);
1964 checkError(res,true);
1965 return res;
1966 #endif
1967 }
1968
efficientSelect()1969 bool Socket::efficientSelect()
1970 {
1971 #if defined(_WINDOWS) || defined(HAVE_POLL)
1972 return true;
1973 #else
1974 return false;
1975 #endif
1976 }
1977
canSelect(SOCKET handle)1978 bool Socket::canSelect(SOCKET handle)
1979 {
1980 if (handle == invalidHandle())
1981 return false;
1982 #ifdef FD_SETSIZE
1983 #ifndef _WINDOWS
1984 #ifndef HAVE_POLL
1985 if (handle >= (SOCKET)FD_SETSIZE)
1986 return false;
1987 #endif
1988 #endif
1989 #endif
1990 return true;
1991 }
1992
select(bool * readok,bool * writeok,bool * except,struct timeval * timeout)1993 bool Socket::select(bool* readok, bool* writeok, bool* except, struct timeval* timeout)
1994 {
1995 SOCKET tmp = m_handle;
1996 if (!valid())
1997 return false;
1998
1999 #ifdef HAVE_POLL
2000 struct pollfd fds;
2001 fds.fd = tmp;
2002 fds.events = 0;
2003 fds.revents = 0;
2004 if (readok)
2005 fds.events |= POLLIN;
2006 if (writeok)
2007 fds.events |= POLLOUT;
2008 if (except)
2009 fds.events |= POLLRDHUP;
2010 int tout = -1;
2011 if (timeout)
2012 tout = (timeout->tv_sec * 1000) + (timeout->tv_usec / 1000);
2013 if (checkError(::poll(&fds,1,tout),true)) {
2014 if (readok)
2015 *readok = (fds.revents & POLLIN) != 0;
2016 if (writeok)
2017 *writeok = (fds.revents & POLLOUT) != 0;
2018 if (except)
2019 *except = (fds.revents & (POLLRDHUP|POLLERR|POLLHUP|POLLNVAL)) != 0;
2020 return true;
2021 }
2022
2023 #else // HAVE_POLL
2024
2025 #ifdef FD_SETSIZE
2026 #ifndef _WINDOWS
2027 static bool localFail = true;
2028 if (tmp >= (SOCKET)FD_SETSIZE) {
2029 if (localFail) {
2030 localFail = false;
2031 Alarm("engine","socket",DebugCrit,"Socket::select: handle %d larger than compiled in maximum %d",
2032 tmp,FD_SETSIZE);
2033 }
2034 return false;
2035 }
2036 #endif
2037 #endif
2038 fd_set readfd,writefd,exceptfd;
2039 fd_set *rfds = 0;
2040 fd_set *wfds = 0;
2041 fd_set *efds = 0;
2042 if (readok) {
2043 rfds = &readfd;
2044 FD_ZERO(rfds);
2045 FD_SET(tmp,rfds);
2046 }
2047 if (writeok) {
2048 wfds = &writefd;
2049 FD_ZERO(wfds);
2050 FD_SET(tmp,wfds);
2051 }
2052 if (except) {
2053 efds = &exceptfd;
2054 FD_ZERO(efds);
2055 FD_SET(tmp,efds);
2056 }
2057 if (checkError(::select(tmp+1,rfds,wfds,efds,timeout),true)) {
2058 if (readok)
2059 *readok = (FD_ISSET(tmp,rfds) != 0);
2060 if (writeok)
2061 *writeok = (FD_ISSET(tmp,wfds) != 0);
2062 if (except)
2063 *except = (FD_ISSET(tmp,efds) != 0);
2064 return true;
2065 }
2066 #endif // HAVE_POLL
2067
2068 if (tmp != m_handle) {
2069 if (except)
2070 *except = true;
2071 return true;
2072 }
2073 return false;
2074 }
2075
select(bool * readok,bool * writeok,bool * except,int64_t timeout)2076 bool Socket::select(bool* readok, bool* writeok, bool* except, int64_t timeout)
2077 {
2078 if (timeout < 0)
2079 return select(readok,writeok,except);
2080 struct timeval tm;
2081 Time::toTimeval(&tm,timeout);
2082 return select(readok,writeok,except,&tm);
2083 }
2084
setOption(int level,int name,const void * value,socklen_t length)2085 bool Socket::setOption(int level, int name, const void* value, socklen_t length)
2086 {
2087 if (!value)
2088 length = 0;
2089 return checkError(::setsockopt(m_handle,level,name,(const char*)value,length));
2090 }
2091
getOption(int level,int name,void * buffer,socklen_t * length)2092 bool Socket::getOption(int level, int name, void* buffer, socklen_t* length)
2093 {
2094 if (length && !buffer)
2095 *length = 0;
2096 return checkError(::getsockopt(m_handle,level,name,(char*)buffer,length));
2097 }
2098
setTOS(int tos)2099 bool Socket::setTOS(int tos)
2100 {
2101 #if defined(AF_INET6) && defined(IPV6_TCLASS)
2102 SocketAddr addr;
2103 if (getSockName(addr) && addr.family() == AF_INET6)
2104 return setOption(IPPROTO_IPV6,IPV6_TCLASS,&tos,sizeof(tos));
2105 #endif
2106 #ifdef IP_TOS
2107 return setOption(IPPROTO_IP,IP_TOS,&tos,sizeof(tos));
2108 #else
2109 if (tos != Normal) {
2110 m_error = ENOTIMPL;
2111 return false;
2112 }
2113 else {
2114 m_error = 0;
2115 return true;
2116 }
2117 #endif
2118 }
2119
getTOS()2120 int Socket::getTOS()
2121 {
2122 int tos = Normal;
2123 socklen_t len = sizeof(tos);
2124 #if defined(AF_INET6) && defined(IPV6_TCLASS)
2125 SocketAddr addr;
2126 if (getSockName(addr) && addr.family() == AF_INET6) {
2127 if (getOption(IPPROTO_IPV6,IPV6_TCLASS,&tos,&len))
2128 return tos;
2129 tos = Normal;
2130 len = sizeof(tos);
2131 }
2132 #endif
2133 #ifdef IP_TOS
2134 getOption(IPPROTO_IP,IP_TOS,&tos,&len);
2135 #else
2136 m_error = ENOTIMPL;
2137 #endif
2138 return tos;
2139 }
2140
setBlocking(bool block)2141 bool Socket::setBlocking(bool block)
2142 {
2143 unsigned long flags = 1;
2144 #ifdef _WINDOWS
2145 if (block)
2146 flags = 0;
2147 return checkError(::ioctlsocket(m_handle,FIONBIO,(unsigned long *) &flags));
2148 #else
2149 flags = ::fcntl(m_handle,F_GETFL);
2150 if ((signed long)flags < 0) {
2151 copyError();
2152 return false;
2153 }
2154 if (block)
2155 flags &= !O_NONBLOCK;
2156 else
2157 flags |= O_NONBLOCK;
2158 return checkError(::fcntl(m_handle,F_SETFL,flags));
2159 #endif
2160 }
2161
setReuse(bool reuse,bool exclusive)2162 bool Socket::setReuse(bool reuse, bool exclusive)
2163 {
2164 int i = reuse ? 1 : 0;
2165 if (!setOption(SOL_SOCKET,SO_REUSEADDR,&i,sizeof(i)))
2166 return false;
2167 #ifdef SO_EXCLUSIVEADDRUSE
2168 i = exclusive ? 1 : 0;
2169 if (!setOption(SOL_SOCKET,SO_EXCLUSIVEADDRUSE,&i,sizeof(i)) && exclusive)
2170 return false;
2171 #else
2172 if (exclusive) {
2173 Debug(DebugMild,"Socket SO_EXCLUSIVEADDRUSE not supported on this platform");
2174 return false;
2175 }
2176 #endif
2177 return true;
2178 }
2179
setLinger(int seconds)2180 bool Socket::setLinger(int seconds)
2181 {
2182 #ifdef SO_DONTLINGER
2183 if (seconds < 0) {
2184 int i = 1;
2185 return setOption(SOL_SOCKET,SO_DONTLINGER,&i,sizeof(i));
2186 }
2187 #endif
2188 linger l;
2189 l.l_onoff = (seconds >= 0) ? 1 : 0;
2190 l.l_linger = (seconds >= 0) ? seconds : 0;
2191 return setOption(SOL_SOCKET,SO_LINGER,&l,sizeof(l));
2192 }
2193
createPair(Socket & sock1,Socket & sock2,int domain)2194 bool Socket::createPair(Socket& sock1, Socket& sock2, int domain)
2195 {
2196 #ifndef _WINDOWS
2197 SOCKET pair[2];
2198 if (!::socketpair(domain,SOCK_STREAM,0,pair)) {
2199 sock1.attach(pair[0]);
2200 sock2.attach(pair[1]);
2201 return true;
2202 }
2203 #endif
2204 return false;
2205 }
2206
installFilter(SocketFilter * filter)2207 bool Socket::installFilter(SocketFilter* filter)
2208 {
2209 if (!filter || filter->socket())
2210 return false;
2211 if (m_filters.find(filter))
2212 return false;
2213 filter->m_socket = this;
2214 m_filters.append(filter);
2215 return true;
2216 }
2217
removeFilter(SocketFilter * filter,bool delobj)2218 void Socket::removeFilter(SocketFilter* filter, bool delobj)
2219 {
2220 if (m_filters.remove(filter,delobj))
2221 filter->m_socket = 0;
2222 }
2223
clearFilters()2224 void Socket::clearFilters()
2225 {
2226 m_filters.clear();
2227 }
2228
applyFilters(void * buffer,int length,int flags,const struct sockaddr * addr,socklen_t adrlen)2229 bool Socket::applyFilters(void* buffer, int length, int flags, const struct sockaddr* addr, socklen_t adrlen)
2230 {
2231 if ((length <= 0) || !buffer)
2232 return false;
2233 if (!addr)
2234 adrlen = 0;
2235 for (ObjList* l = &m_filters; l; l = l->next()) {
2236 SocketFilter* filter = static_cast<SocketFilter*>(l->get());
2237 if (filter && filter->received(buffer,length,flags,addr,adrlen))
2238 return true;
2239 }
2240 return false;
2241 }
2242
timerTick(const Time & when)2243 void Socket::timerTick(const Time& when)
2244 {
2245 for (ObjList* l = &m_filters; l; l = l->next()) {
2246 SocketFilter* filter = static_cast<SocketFilter*>(l->get());
2247 if (filter)
2248 filter->timerTick(when);
2249 }
2250 }
2251
2252
~SctpSocket()2253 SctpSocket::~SctpSocket()
2254 {
2255 }
2256
2257 /* vi: set ts=8 sw=4 sts=4 noet: */
2258