ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/AnyEvent-FastPing/FastPing.xs
(Generate patch)

Comparing AnyEvent-FastPing/FastPing.xs (file contents):
Revision 1.12 by root, Wed Feb 2 19:26:45 2011 UTC vs.
Revision 1.13 by root, Sat Feb 5 23:37:21 2011 UTC

18#include <poll.h> 18#include <poll.h>
19#include <unistd.h> 19#include <unistd.h>
20#include <inttypes.h> 20#include <inttypes.h>
21#include <fcntl.h> 21#include <fcntl.h>
22#include <errno.h> 22#include <errno.h>
23#include <limits.h>
23 24
24#include <sys/types.h> 25#include <sys/types.h>
25#include <sys/time.h> 26#include <sys/time.h>
26#include <sys/socket.h> 27#include <sys/socket.h>
27 28
237static int 238static int
238range_send_ping (RANGE *self, PKT *pkt) 239range_send_ping (RANGE *self, PKT *pkt)
239{ 240{
240 // send ping 241 // send ping
241 uint8_t *addr; 242 uint8_t *addr;
243 int addrlen;
242 244
243 if (self->addrcnt) 245 if (self->addrcnt)
244 addr = (self->addrcnt - 1) * self->addrlen + (uint8_t *)(self + 1); 246 addr = (self->addrcnt - 1) * self->addrlen + (uint8_t *)(self + 1);
245 else 247 else
246 addr = sizeof (addr_tt) - self->addrlen + self->lo; 248 addr = sizeof (addr_tt) - self->addrlen + self->lo;
247 249
250 addrlen = self->addrlen;
251
252 /* convert ipv4 mapped addresses - this only works for host lists */
253 /* this tries to match 0000:0000:0000:0000:0000:ffff:a.b.c.d */
254 /* efficiently but also with few insns */
255 if (addrlen == 16 && !addr [0] && icmp4_fd >= 0
256 && !( addr [ 1]
257 | addr [ 2] | addr [ 3]
258 | addr [ 4] | addr [ 5]
259 | addr [ 6] | addr [ 7]
260 | addr [ 8] | addr [ 9]
261 | (255-addr [10]) | (255-addr [11])))
262 {
263 addr += 12;
264 addrlen -= 12;
265 }
266
248 pkt->cksum = 0; 267 pkt->cksum = 0;
249 268
250 if (self->addrlen == 4) 269 if (addrlen == 4)
251 { 270 {
252 struct sockaddr_in sa; 271 struct sockaddr_in sa;
253 272
254 pkt->type = ICMP4_ECHO; 273 pkt->type = ICMP4_ECHO;
255 pkt_cksum (pkt); 274 pkt_cksum (pkt);
421 440
422 return 0; 441 return 0;
423} 442}
424 443
425/*****************************************************************************/ 444/*****************************************************************************/
445
446/* NetBSD, Solaris... */
447#ifndef PTHREAD_STACK_MIN
448# define PTHREAD_STACK_MIN 0
449#endif
426 450
427static void 451static void
428pinger_start (PINGER *self) 452pinger_start (PINGER *self)
429{ 453{
430 sigset_t fullsigset, oldsigset; 454 sigset_t fullsigset, oldsigset;
842 CODE: 866 CODE:
843{ 867{
844 AV *av; 868 AV *av;
845 int i, j, k; 869 int i, j, k;
846 int cnt; 870 int cnt;
847 int addrlen; 871 int addrlen = 0;
848 RANGE *range; 872 RANGE *range;
849 NOT_RUNNING; 873 NOT_RUNNING;
850 874
851 if (!SvROK (addrs) || SvTYPE (SvRV (addrs)) != SVt_PVAV) 875 if (!SvROK (addrs) || SvTYPE (SvRV (addrs)) != SVt_PVAV)
852 croak ("AnyEvent::FastPing::add_hosts expects an arrayref with binary IPv4 or IPv6 addresses"); 876 croak ("AnyEvent::FastPing::add_hosts expects an arrayref with binary IPv4 or IPv6 addresses");
853 877
854 av = (AV *)SvRV (addrs); 878 av = (AV *)SvRV (addrs);
855 cnt = av_len (av) + 1; 879 cnt = av_len (av) + 1;
856 880
881 for (i = 0; i < cnt; ++i)
882 {
883 SV *sv = *av_fetch (av, i, 1);
884 sv_utf8_downgrade (sv, 0);
885
886 j = SvCUR (sv);
887
888 if (j != 4 && j != 16)
889 croak ("AnyEvent::FastPing::add_hosts addresses must be specified as binary IPv4 or IPv6 addresses");
890
891 if (j > addrlen)
892 addrlen = j;
893 }
894
857 if (!cnt) 895 if (!cnt)
858 XSRETURN_EMPTY; 896 XSRETURN_EMPTY;
859
860 addrlen = SvCUR (*av_fetch (av, 0, 1));
861
862 if (addrlen != 4 && addrlen != 16)
863 croak ("AnyEvent::FastPing::add_hosts addresses must be specified as binary IPv4 or IPv6 addresses");
864
865 for (i = cnt; --i; )
866 {
867 SV *sv = *av_fetch (av, i, 1);
868
869 if (!sv_utf8_downgrade (sv, 1) || addrlen != SvCUR (sv))
870 croak ("AnyEvent::FastPing::add_hosts addresses must all have the same size");
871 }
872 897
873 range = calloc (1, sizeof (RANGE) + cnt * addrlen); 898 range = calloc (1, sizeof (RANGE) + cnt * addrlen);
874 899
875 range->next = 0; 900 range->next = 0;
876 range->interval = interval > MIN_INTERVAL ? interval : MIN_INTERVAL; 901 range->interval = interval > MIN_INTERVAL ? interval : MIN_INTERVAL;
881 interleave = cnt <= 256 * 256 ? 256 : (int)sqrtf (cnt); 906 interleave = cnt <= 256 * 256 ? 256 : (int)sqrtf (cnt);
882 907
883 k = cnt; 908 k = cnt;
884 for (j = 0; j < interleave; ++j) 909 for (j = 0; j < interleave; ++j)
885 for (i = j; i < cnt; i += interleave) 910 for (i = j; i < cnt; i += interleave)
911 {
886 memcpy ((uint8_t *)(range + 1) + --k * addrlen, 912 uint8_t *dst = (uint8_t *)(range + 1) + --k * addrlen;
887 SvPVbyte_nolen (*av_fetch (av, i, 1)), 913 char *pv;
888 addrlen); 914 STRLEN pvlen;
915 SV *sv = *av_fetch (av, i, 1);
916 sv_utf8_downgrade (sv, 0);
917
918 pv = SvPVbyte (sv, pvlen);
919
920 if (pvlen != addrlen)
921 {
922 dst [ 0] = 0x00; dst [ 1] = 0x00; dst [ 2] = 0x00; dst [ 3] = 0x00;
923 dst [ 4] = 0x00; dst [ 5] = 0x00; dst [ 6] = 0x00; dst [ 7] = 0x00;
924 dst [ 8] = 0x00; dst [ 9] = 0x00; dst [10] = 0xff; dst [11] = 0xff;
925 dst [12] = pv [0]; dst [13] = pv [1]; dst [14] = pv [2]; dst [15] = pv [3];
926 }
927 else
928 memcpy (dst, pv, addrlen);
929 }
889 930
890 pinger_add_range (self, range); 931 pinger_add_range (self, range);
891} 932}
892 933

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines