Diff for /embedaddon/dnsmasq/src/util.c between versions 1.1 and 1.1.1.3

version 1.1, 2013/07/29 19:37:40 version 1.1.1.3, 2016/11/02 09:57:01
Line 1 Line 1
/* dnsmasq is Copyright (c) 2000-2013 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 28 Line 28
 #include <idna.h>  #include <idna.h>
 #endif  #endif
   
 #ifdef HAVE_ARC4RANDOM  
 void rand_init(void)  
 {  
   return;  
 }  
   
 unsigned short rand16(void)  
 {  
    return (unsigned short) (arc4random() >> 15);  
 }  
   
 #else  
   
 /* SURF random number generator */  /* SURF random number generator */
   
 static u32 seed[32];  static u32 seed[32];
 static u32 in[12];  static u32 in[12];
 static u32 out[8];  static u32 out[8];
   static int outleft = 0;
   
 void rand_init()  void rand_init()
 {  {
Line 83  static void surf(void) Line 71  static void surf(void)
   
 unsigned short rand16(void)  unsigned short rand16(void)
 {  {
     if (!outleft) 
       {
         if (!++in[0]) if (!++in[1]) if (!++in[2]) ++in[3];
         surf();
         outleft = 8;
       }
     
     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)
   {
   static int outleft = 0;    static int outleft = 0;
   
  if (!outleft) {  if (outleft < 2)
    if (!++in[0]) if (!++in[1]) if (!++in[2]) ++in[3];    {
    surf();      if (!++in[0]) if (!++in[1]) if (!++in[2]) ++in[3];
    outleft = 8;      surf();
  }      outleft = 8;
     }
   
   outleft -= 2;
   
  return (unsigned short) out[--outleft];  return (u64)out[outleft+1] + (((u64)out[outleft]) << 32);
 }  }
   
 #endif  
   
 static int check_name(char *in)  static int check_name(char *in)
 {  {
   /* remove trailing .     /* remove trailing . 
Line 108  static int check_name(char *in) Line 121  static int check_name(char *in)
       
   if (in[l-1] == '.')    if (in[l-1] == '.')
     {      {
       if (l == 1) return 0;  
       in[l-1] = 0;        in[l-1] = 0;
         nowhite = 1;
     }      }
  
   for (; (c = *in); in++)    for (; (c = *in); in++)
     {      {
       if (c == '.')        if (c == '.')
Line 142  static int check_name(char *in) Line 155  static int check_name(char *in)
 int legal_hostname(char *name)  int legal_hostname(char *name)
 {  {
   char c;    char c;
     int first;
   
   if (!check_name(name))    if (!check_name(name))
     return 0;      return 0;
   
  for (; (c = *name); name++)  for (first = 1; (c = *name); name++, first = 0)
     /* check for legal char a-z A-Z 0-9 - _ . */      /* check for legal char a-z A-Z 0-9 - _ . */
     {      {
       if ((c >= 'A' && c <= 'Z') ||        if ((c >= 'A' && c <= 'Z') ||
           (c >= 'a' && c <= 'z') ||            (c >= 'a' && c <= 'z') ||
          (c >= '0' && c <= '9') ||          (c >= '0' && c <= '9'))
          c == '-' || c == '_') 
         continue;          continue;
   
         if (!first && (c == '-' || c == '_'))
           continue;
               
       /* end of hostname part */        /* end of hostname part */
       if (c == '.')        if (c == '.')
Line 210  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 258  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 315  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 454  int parse_hex(char *in, unsigned char *out, int maxlen Line 491  int parse_hex(char *in, unsigned char *out, int maxlen
                   int j, bytes = (1 + (r - in))/2;                    int j, bytes = (1 + (r - in))/2;
                   for (j = 0; j < bytes; j++)                    for (j = 0; j < bytes; j++)
                     {                       { 
                      char sav;                      char sav = sav;
                       if (j < bytes - 1)                        if (j < bytes - 1)
                         {                          {
                           sav = in[(j+1)*2];                            sav = in[(j+1)*2];
Line 533  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 562  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 597  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);
 }  }

Removed from v.1.1  
changed lines
  Added in v.1.1.1.3


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>