Diff for /embedaddon/dnsmasq/src/tftp.c between versions 1.1.1.1 and 1.1.1.3

version 1.1.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 49  void tftp_request(struct listener *listen, time_t now) Line 49  void tftp_request(struct listener *listen, time_t now)
   struct iovec iov;    struct iovec iov;
   struct ifreq ifr;    struct ifreq ifr;
   int is_err = 1, if_index = 0, mtu = 0;    int is_err = 1, if_index = 0, mtu = 0;
 #ifdef HAVE_DHCP  
   struct iname *tmp;    struct iname *tmp;
 #endif  
   struct tftp_transfer *transfer;    struct tftp_transfer *transfer;
   int port = daemon->start_tftp_port; /* may be zero to use ephemeral port */    int port = daemon->start_tftp_port; /* may be zero to use ephemeral port */
 #if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)  #if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
Line 62  void tftp_request(struct listener *listen, time_t now) Line 60  void tftp_request(struct listener *listen, time_t now)
   char *prefix = daemon->tftp_prefix;    char *prefix = daemon->tftp_prefix;
   struct tftp_prefix *pref;    struct tftp_prefix *pref;
   struct all_addr addra;    struct all_addr addra;
#ifdef HAVE_IPV6
   /* Can always get recvd interface for IPv6 */
   int check_dest = !option_bool(OPT_NOWILD) || listen->family == AF_INET6;
 #else
   int check_dest = !option_bool(OPT_NOWILD);
 #endif
   union {    union {
     struct cmsghdr align; /* this ensures alignment */      struct cmsghdr align; /* this ensures alignment */
 #ifdef HAVE_IPV6  #ifdef HAVE_IPV6
Line 93  void tftp_request(struct listener *listen, time_t now) Line 96  void tftp_request(struct listener *listen, time_t now)
   
   if ((len = recvmsg(listen->tftpfd, &msg, 0)) < 2)    if ((len = recvmsg(listen->tftpfd, &msg, 0)) < 2)
     return;      return;
  
  if (option_bool(OPT_NOWILD))  /* Can always get recvd interface for IPv6 */
   if (!check_dest)
     {      {
       if (listen->iface)        if (listen->iface)
         {          {
           addr = listen->iface->addr;            addr = listen->iface->addr;
           mtu = listen->iface->mtu;  
           name = listen->iface->name;            name = listen->iface->name;
             mtu = listen->iface->mtu;
             if (daemon->tftp_mtu != 0 && daemon->tftp_mtu < mtu)
               mtu = daemon->tftp_mtu;
         }          }
       else        else
         {          {
Line 198  void tftp_request(struct listener *listen, time_t now) Line 204  void tftp_request(struct listener *listen, time_t now)
         addra.addr.addr6 = addr.in6.sin6_addr;          addra.addr.addr6 = addr.in6.sin6_addr;
 #endif  #endif
   
      if (!iface_check(listen->family, &addra, name, NULL))      if (daemon->tftp_interfaces)
         {          {
          if (!option_bool(OPT_CLEVERBIND))          /* dedicated tftp interface list */
            enumerate_interfaces();           for (tmp = daemon->tftp_interfaces; tmp; tmp = tmp->next)
          if (!loopback_exception(listen->tftpfd, listen->family, &addra, name))            if (tmp->name && wildcard_match(tmp->name, name))
               break;
 
           if (!tmp)
             return;              return;
         }          }
            else
         {
           /* Do the same as DHCP */
           if (!iface_check(listen->family, &addra, name, NULL))
             {
               if (!option_bool(OPT_CLEVERBIND))
                 enumerate_interfaces(0)
               if (!loopback_exception(listen->tftpfd, listen->family, &addra, name) &&
                   !label_exception(if_index, listen->family, &addra) )
                 return;
             }
           
 #ifdef HAVE_DHCP        #ifdef HAVE_DHCP      
      /* allowed interfaces are the same as for DHCP */          /* allowed interfaces are the same as for DHCP */
      for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next)          for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next)
        if (tmp->name && wildcard_match(tmp->name, name))            if (tmp->name && wildcard_match(tmp->name, name))
          return;              return;
 #endif  #endif
              }
 
       strncpy(ifr.ifr_name, name, IF_NAMESIZE);        strncpy(ifr.ifr_name, name, IF_NAMESIZE);
       if (ioctl(listen->tftpfd, SIOCGIFMTU, &ifr) != -1)        if (ioctl(listen->tftpfd, SIOCGIFMTU, &ifr) != -1)
        mtu = ifr.ifr_mtu;              {
           mtu = ifr.ifr_mtu;  
           if (daemon->tftp_mtu != 0 && daemon->tftp_mtu < mtu)
             mtu = daemon->tftp_mtu;    
         }
     }      }
  
   /* Failed to get interface mtu - can use configured value. */
   if (mtu == 0)
     mtu = daemon->tftp_mtu;
 
   if (name)    if (name)
     {      {
       /* check for per-interface prefix */         /* check for per-interface prefix */ 
Line 317  void tftp_request(struct listener *listen, time_t now) Line 346  void tftp_request(struct listener *listen, time_t now)
             {              {
               if ((opt = next(&p, end)) && !option_bool(OPT_TFTP_NOBLOCK))                if ((opt = next(&p, end)) && !option_bool(OPT_TFTP_NOBLOCK))
                 {                  {
                     /* 32 bytes for IP, UDP and TFTP headers, 52 bytes for IPv6 */
                     int overhead = (listen->family == AF_INET) ? 32 : 52;
                   transfer->blocksize = atoi(opt);                    transfer->blocksize = atoi(opt);
                   if (transfer->blocksize < 1)                    if (transfer->blocksize < 1)
                     transfer->blocksize = 1;                      transfer->blocksize = 1;
                   if (transfer->blocksize > (unsigned)daemon->packet_buff_sz - 4)                    if (transfer->blocksize > (unsigned)daemon->packet_buff_sz - 4)
                     transfer->blocksize = (unsigned)daemon->packet_buff_sz - 4;                      transfer->blocksize = (unsigned)daemon->packet_buff_sz - 4;
                  /* 32 bytes for IP, UDP and TFTP headers */                  if (mtu != 0 && transfer->blocksize > (unsigned)mtu - overhead)
                  if (mtu != 0 && transfer->blocksize > (unsigned)mtu - 32)                    transfer->blocksize = (unsigned)mtu - overhead;
                    transfer->blocksize = (unsigned)mtu - 32; 
                   transfer->opt_blocksize = 1;                    transfer->opt_blocksize = 1;
                   transfer->block = 0;                    transfer->block = 0;
                 }                  }
Line 483  static struct tftp_file *check_tftp_fileperm(ssize_t * Line 513  static struct tftp_file *check_tftp_fileperm(ssize_t *
   return NULL;    return NULL;
 }  }
   
void check_tftp_listeners(fd_set *rset, time_t now)void check_tftp_listeners(time_t now)
 {  {
   struct tftp_transfer *transfer, *tmp, **up;    struct tftp_transfer *transfer, *tmp, **up;
   ssize_t len;    ssize_t len;
Line 499  void check_tftp_listeners(fd_set *rset, time_t now) Line 529  void check_tftp_listeners(fd_set *rset, time_t now)
               
       prettyprint_addr(&transfer->peer, daemon->addrbuff);        prettyprint_addr(&transfer->peer, daemon->addrbuff);
             
      if (FD_ISSET(transfer->sockfd, rset))      if (poll_check(transfer->sockfd, POLLIN))
         {          {
           /* we overwrote the buffer... */            /* we overwrote the buffer... */
           daemon->srv_save = NULL;            daemon->srv_save = NULL;
Line 554  void check_tftp_listeners(fd_set *rset, time_t now) Line 584  void check_tftp_listeners(fd_set *rset, time_t now)
             }              }
           /* don't complain about timeout when we're awaiting the last            /* don't complain about timeout when we're awaiting the last
              ACK, some clients never send it */               ACK, some clients never send it */
          else if (++transfer->backoff > 5 && len != 0)          else if (++transfer->backoff > 7 && len != 0)
             {              {
               endcon = 1;                endcon = 1;
               len = 0;                len = 0;

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


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