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