version 1.1.1.2, 2014/06/15 16:31:38
|
version 1.1.1.3, 2016/11/02 09:57:01
|
Line 1
|
Line 1
|
/* dnsmasq is Copyright (c) 2000-2014 Simon Kelley | /* dnsmasq is Copyright (c) 2000-2016 Simon Kelley |
|
|
This program is free software; you can redistribute it and/or modify |
This program is free software; you can redistribute it and/or modify |
it under the terms of the GNU General Public License as published by |
it under the terms of the GNU General Public License as published by |
Line 81 unsigned short rand16(void)
|
Line 81 unsigned short rand16(void)
|
return (unsigned short) out[--outleft]; |
return (unsigned short) out[--outleft]; |
} |
} |
|
|
|
u32 rand32(void) |
|
{ |
|
if (!outleft) |
|
{ |
|
if (!++in[0]) if (!++in[1]) if (!++in[2]) ++in[3]; |
|
surf(); |
|
outleft = 8; |
|
} |
|
|
|
return out[--outleft]; |
|
} |
|
|
u64 rand64(void) |
u64 rand64(void) |
{ |
{ |
static int outleft = 0; |
static int outleft = 0; |
Line 214 unsigned char *do_rfc1035_name(unsigned char *p, char
|
Line 226 unsigned char *do_rfc1035_name(unsigned char *p, char
|
{ |
{ |
unsigned char *cp = p++; |
unsigned char *cp = p++; |
for (j = 0; *sval && (*sval != '.'); sval++, j++) |
for (j = 0; *sval && (*sval != '.'); sval++, j++) |
*p++ = *sval; | { |
| #ifdef HAVE_DNSSEC |
| if (option_bool(OPT_DNSSEC_VALID) && *sval == NAME_ESCAPE) |
| *p++ = (*(++sval))-1; |
| else |
| #endif |
| *p++ = *sval; |
| } |
*cp = j; |
*cp = j; |
if (*sval) |
if (*sval) |
sval++; |
sval++; |
Line 262 int sockaddr_isequal(union mysockaddr *s1, union mysoc
|
Line 281 int sockaddr_isequal(union mysockaddr *s1, union mysoc
|
#ifdef HAVE_IPV6 |
#ifdef HAVE_IPV6 |
if (s1->sa.sa_family == AF_INET6 && |
if (s1->sa.sa_family == AF_INET6 && |
s1->in6.sin6_port == s2->in6.sin6_port && |
s1->in6.sin6_port == s2->in6.sin6_port && |
|
s1->in6.sin6_scope_id == s2->in6.sin6_scope_id && |
IN6_ARE_ADDR_EQUAL(&s1->in6.sin6_addr, &s2->in6.sin6_addr)) |
IN6_ARE_ADDR_EQUAL(&s1->in6.sin6_addr, &s2->in6.sin6_addr)) |
return 1; |
return 1; |
#endif |
#endif |
Line 319 time_t dnsmasq_time(void)
|
Line 339 time_t dnsmasq_time(void)
|
#endif |
#endif |
} |
} |
|
|
|
int netmask_length(struct in_addr mask) |
|
{ |
|
int zero_count = 0; |
|
|
|
while (0x0 == (mask.s_addr & 0x1) && zero_count < 32) |
|
{ |
|
mask.s_addr >>= 1; |
|
zero_count++; |
|
} |
|
|
|
return 32 - zero_count; |
|
} |
|
|
int is_same_net(struct in_addr a, struct in_addr b, struct in_addr mask) |
int is_same_net(struct in_addr a, struct in_addr b, struct in_addr mask) |
{ |
{ |
return (a.s_addr & mask.s_addr) == (b.s_addr & mask.s_addr); |
return (a.s_addr & mask.s_addr) == (b.s_addr & mask.s_addr); |
Line 537 char *print_mac(char *buff, unsigned char *mac, int le
|
Line 570 char *print_mac(char *buff, unsigned char *mac, int le
|
return buff; |
return buff; |
} |
} |
|
|
void bump_maxfd(int fd, int *max) | /* rc is return from sendto and friends. |
| Return 1 if we should retry. |
| Set errno to zero if we succeeded. */ |
| int retry_send(ssize_t rc) |
{ |
{ |
if (fd > *max) | static int retries = 0; |
*max = fd; | struct timespec waiter; |
} | |
| if (rc != -1) |
| { |
| retries = 0; |
| errno = 0; |
| return 0; |
| } |
| |
| /* Linux kernels can return EAGAIN in perpetuity when calling |
| sendmsg() and the relevant interface has gone. Here we loop |
| retrying in EAGAIN for 1 second max, to avoid this hanging |
| dnsmasq. */ |
|
|
int retry_send(void) | if (errno == EAGAIN || errno == EWOULDBLOCK) |
{ | |
struct timespec waiter; | |
if (errno == EAGAIN || errno == EWOULDBLOCK) | |
{ |
{ |
waiter.tv_sec = 0; |
waiter.tv_sec = 0; |
waiter.tv_nsec = 10000; |
waiter.tv_nsec = 10000; |
nanosleep(&waiter, NULL); |
nanosleep(&waiter, NULL); |
return 1; | if (retries++ < 1000) |
| return 1; |
} |
} |
| |
if (errno == EINTR) | retries = 0; |
return 1; | |
| if (errno == EINTR) |
return 0; | return 1; |
| |
| return 0; |
} |
} |
|
|
int read_write(int fd, unsigned char *packet, int size, int rw) |
int read_write(int fd, unsigned char *packet, int size, int rw) |
Line 566 int read_write(int fd, unsigned char *packet, int size
|
Line 613 int read_write(int fd, unsigned char *packet, int size
|
|
|
for (done = 0; done < size; done += n) |
for (done = 0; done < size; done += n) |
{ |
{ |
retry: | do { |
if (rw) | if (rw) |
n = read(fd, &packet[done], (size_t)(size - done)); | n = read(fd, &packet[done], (size_t)(size - done)); |
else | else |
n = write(fd, &packet[done], (size_t)(size - done)); | n = write(fd, &packet[done], (size_t)(size - done)); |
| |
| if (n == 0) |
| return 0; |
| |
| } while (retry_send(n) || errno == ENOMEM || errno == ENOBUFS); |
|
|
if (n == 0) | if (errno != 0) |
return 0; | return 0; |
else if (n == -1) | |
{ | |
if (retry_send() || errno == ENOMEM || errno == ENOBUFS) | |
goto retry; | |
else | |
return 0; | |
} | |
} |
} |
|
|
return 1; |
return 1; |
} |
} |
|
|
Line 601 int wildcard_match(const char* wildcard, const char* m
|
Line 647 int wildcard_match(const char* wildcard, const char* m
|
} |
} |
|
|
return *wildcard == *match; |
return *wildcard == *match; |
|
} |
|
|
|
/* The same but comparing a maximum of NUM characters, like strncmp. */ |
|
int wildcard_matchn(const char* wildcard, const char* match, int num) |
|
{ |
|
while (*wildcard && *match && num) |
|
{ |
|
if (*wildcard == '*') |
|
return 1; |
|
|
|
if (*wildcard != *match) |
|
return 0; |
|
|
|
++wildcard; |
|
++match; |
|
--num; |
|
} |
|
|
|
return (!num) || (*wildcard == *match); |
} |
} |