[BACK]Return to udp_usrreq.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / netinet

Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.

Diff for /src/sys/netinet/udp_usrreq.c between version 1.190.2.2 and 1.190.2.3

version 1.190.2.2, 2013/08/28 15:21:48 version 1.190.2.3, 2013/09/23 00:57:53
Line 575  udp4_realinput(struct sockaddr_in *src, 
Line 575  udp4_realinput(struct sockaddr_in *src, 
                  */                   */
                 struct socket *so;                  struct socket *so;
   
                 inp = inpcb_lookup_connect(udbtable, *src4, *sport, *dst4,                  inp = inpcb_lookup(udbtable, *src4, *sport, *dst4, *dport, NULL);
                     *dport, 0);  
                 if (inp == NULL) {                  if (inp == NULL) {
                         UDP_STATINC(UDP_STAT_PCBHASHMISS);                          UDP_STATINC(UDP_STAT_PCBHASHMISS);
                         inp = inpcb_lookup_bind(udbtable, *dst4, *dport);                          inp = inpcb_lookup_bound(udbtable, *dst4, *dport);
                         if (inp == NULL)                          if (inp == NULL)
                                 return rcvcnt;                                  return rcvcnt;
                 }                  }
Line 753  end:
Line 752  end:
         return error;          return error;
 }  }
   
   static int
 int  udp_output(struct mbuf *m, inpcb_t *inp)
 udp_output(struct mbuf *m, ...)  
 {  {
         inpcb_t *inp;  
         struct socket *so;          struct socket *so;
         struct udpiphdr *ui;          struct udpiphdr *ui;
         struct route *ro;          struct route *ro;
         int len = m->m_pkthdr.len;          int len = m->m_pkthdr.len;
         int error = 0;          int error = 0;
         va_list ap;  
   
         MCLAIM(m, &udp_tx_mowner);          MCLAIM(m, &udp_tx_mowner);
         va_start(ap, m);  
         inp = va_arg(ap, inpcb_t *);  
         va_end(ap);  
   
         so = inpcb_get_socket(inp);          so = inpcb_get_socket(inp);
         KASSERT(solocked(so));          KASSERT(solocked(so));
   
         /*          /*
          * Calculate data length and get a mbuf           * Calculate data length and get a mbuf for UDP and IP headers.
          * for UDP and IP headers.  
          */           */
         M_PREPEND(m, sizeof(struct udpiphdr), M_DONTWAIT);          M_PREPEND(m, sizeof(struct udpiphdr), M_DONTWAIT);
         if (m == 0) {          if (m == NULL) {
                 error = ENOBUFS;                  error = ENOBUFS;
                 goto release;                  goto release;
         }          }
Line 793  udp_output(struct mbuf *m, ...)
Line 784  udp_output(struct mbuf *m, ...)
         }          }
   
         /*          /*
          * Fill in mbuf with extended UDP header           * Fill in mbuf with extended UDP header.
          * and addresses and length put into network format.  
          */           */
         ui = mtod(m, struct udpiphdr *);          ui = mtod(m, struct udpiphdr *);
         ui->ui_pr = IPPROTO_UDP;          ui->ui_pr = IPPROTO_UDP;
   
         inpcb_get_addrs(inp, &ui->ui_src, &ui->ui_dst);          inpcb_get_addrs(inp, &ui->ui_src, &ui->ui_dst);
         inpcb_get_ports(inp, &ui->ui_sport, &ui->ui_dport);          inpcb_get_ports(inp, &ui->ui_sport, &ui->ui_dport);
         ui->ui_ulen = htons((u_int16_t)len + sizeof(struct udphdr));          ui->ui_ulen = htons((uint16_t)len + sizeof(struct udphdr));
   
         ro = inpcb_get_route(inp);          ro = inpcb_get_route(inp);
   
Line 821  udp_output(struct mbuf *m, ...)
Line 810  udp_output(struct mbuf *m, ...)
         } else          } else
                 ui->ui_sum = 0;                  ui->ui_sum = 0;
   
         ((struct ip *)ui)->ip_len = htons(sizeof (struct udpiphdr) + len);          struct ip *ui_ip = (struct ip *)ui;
           ui_ip->ip_len = htons(sizeof (struct udpiphdr) + len);
   
         struct ip *inp_ip = in_getiphdr(inp);          struct ip *inp_ip = in_getiphdr(inp);
         ((struct ip *)ui)->ip_ttl = inp_ip->ip_ttl;     /* XXX */          ui_ip->ip_ttl = inp_ip->ip_ttl; /* XXX */
         ((struct ip *)ui)->ip_tos = inp_ip->ip_tos;     /* XXX */          ui_ip->ip_tos = inp_ip->ip_tos; /* XXX */
         UDP_STATINC(UDP_STAT_OPACKETS);          UDP_STATINC(UDP_STAT_OPACKETS);
   
         return (ip_output(m, inpcb_get_options(inp), ro,          return (ip_output(m, inpcb_get_options(inp), ro,
Line 889  udp_detach(struct socket *so)
Line 879  udp_detach(struct socket *so)
 }  }
   
 static int  static int
   udp_send(struct socket *so, struct mbuf *m, struct mbuf *nam,
       struct mbuf *control)
   {
           inpcb_t *inp;
           struct in_addr laddr;
           int error;
   
           KASSERT(solocked(so));
           inp = sotoinpcb(so);
   
           if (control && control->m_len) {
                   m_freem(control);
                   m_freem(m);
                   return EINVAL;
           }
   
           if ((so->so_state & SS_ISCONNECTED) != 0) {
                   m_freem(m);
                   return nam ? EISCONN : ENOTCONN;
           }
   
           if (nam) {
                   /*
                    * XXX: sendto() case - temporarily connect the socket
                    * to the destination, send and then disconnect.  Also,
                    * preserve the local address as it may be changed.
                    */
                   inpcb_get_addrs(inp, &laddr, NULL);
                   if ((error = inpcb_connect(inp, nam, curlwp)) != 0) {
                           m_freem(m);
                           return error;
                   }
           }
           error = udp_output(m, inp);
           if (nam) {
                   inpcb_disconnect(inp);
                   inpcb_set_addrs(inp, &laddr, NULL);
                   inpcb_set_state(inp, INP_BOUND);
           }
           return error;
   }
   
   static int
 udp_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,  udp_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
     struct mbuf *control, struct lwp *l)      struct mbuf *control, struct lwp *l)
 {  {
Line 921  udp_usrreq(struct socket *so, int req, s
Line 954  udp_usrreq(struct socket *so, int req, s
                 goto release;                  goto release;
         }          }
   
         /*  
          * Note: need to block udp_input while changing  
          * the udp pcb queue and/or pcb addresses.  
          */  
         switch (req) {          switch (req) {
         case PRU_BIND:          case PRU_BIND:
                 error = inpcb_bind(inp, nam, l);                  error = inpcb_bind(inp, nam, l);
Line 949  udp_usrreq(struct socket *so, int req, s
Line 978  udp_usrreq(struct socket *so, int req, s
                 /*soisdisconnected(so);*/                  /*soisdisconnected(so);*/
                 so->so_state &= ~SS_ISCONNECTED;                /* XXX */                  so->so_state &= ~SS_ISCONNECTED;                /* XXX */
                 inpcb_disconnect(inp);                  inpcb_disconnect(inp);
                 inpcb_set_addrs(inp, &zeroin_addr, NULL);       /* XXX */  
                 inpcb_set_state(inp, INP_BOUND);                /* XXX */  
                 break;                  break;
   
         case PRU_SHUTDOWN:          case PRU_SHUTDOWN:
Line 962  udp_usrreq(struct socket *so, int req, s
Line 989  udp_usrreq(struct socket *so, int req, s
                 break;                  break;
   
         case PRU_SEND:          case PRU_SEND:
                 if (control && control->m_len) {                  error = udp_send(so, m, nam, control);
                         m_freem(control);  
                         m_freem(m);  
                         error = EINVAL;  
                         break;  
                 }  
         {  
                 /*  
                  * Note: sendto case - temporarily connect the socket  
                  * to the destination, send and then disconnect.  
                  * XXX: save the local address, restore after.  
                  */  
                 struct in_addr laddr;  
   
                 memset(&laddr, 0, sizeof laddr);  
                 if (nam) {  
                         inpcb_get_addrs(inp, &laddr, NULL);  
                         if ((so->so_state & SS_ISCONNECTED) != 0) {  
                                 error = EISCONN;  
                                 goto die;  
                         }  
                         error = inpcb_connect(inp, nam, l);  
                         if (error)  
                                 goto die;  
                 } else {  
                         if ((so->so_state & SS_ISCONNECTED) == 0) {  
                                 error = ENOTCONN;  
                                 goto die;  
                         }  
                 }  
                 error = udp_output(m, inp);  
                 m = NULL;  
                 if (nam) {  
                         inpcb_disconnect(inp);  
                         inpcb_set_addrs(inp, &laddr, NULL);  
                         inpcb_set_state(inp, INP_BOUND);  
                 }  
 die:  
                 if (m)  
                         m_freem(m);  
         }  
                 break;                  break;
   
         case PRU_SENSE:          case PRU_SENSE:

Legend:
Removed from v.1.190.2.2  
changed lines
  Added in v.1.190.2.3

CVSweb <webmaster@jp.NetBSD.org>