patch-2.1.124 linux/net/ipv6/udp.c
Next file: linux/net/netlink/af_netlink.c
Previous file: linux/net/ipv6/tcp_ipv6.c
Back to the patch index
Back to the overall index
- Lines: 124
- Date:
Sun Oct 4 10:19:40 1998
- Orig file:
v2.1.123/linux/net/ipv6/udp.c
- Orig date:
Thu Sep 17 17:53:40 1998
diff -u --recursive --new-file v2.1.123/linux/net/ipv6/udp.c linux/net/ipv6/udp.c
@@ -7,7 +7,7 @@
*
* Based on linux/ipv4/udp.c
*
- * $Id: udp.c,v 1.35 1998/09/07 00:13:57 davem Exp $
+ * $Id: udp.c,v 1.36 1998/10/03 09:38:54 davem Exp $
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -332,32 +332,22 @@
struct sk_buff *skb;
int copied, err;
- /*
- * Check any passed addresses
- */
-
- if (addr_len)
+ if (addr_len)
*addr_len=sizeof(struct sockaddr_in6);
- /*
- * From here the generic datagram does a lot of the work. Come
- * the finished NET3, it will do _ALL_ the work!
- */
+ if (flags & MSG_ERRQUEUE)
+ return ipv6_recv_error(sk, msg, len);
skb = skb_recv_datagram(sk, flags, noblock, &err);
if (!skb)
goto out;
-
+
copied = skb->len - sizeof(struct udphdr);
if (copied > len) {
copied = len;
msg->msg_flags |= MSG_TRUNC;
}
- /*
- * FIXME : should use udp header size info value
- */
-
#ifndef CONFIG_UDP_DELAY_CSUM
err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr),
msg->msg_iov, copied);
@@ -395,7 +385,7 @@
#endif
if (err)
goto out_free;
-
+
sk->stamp=skb->stamp;
/* Copy the address. */
@@ -445,26 +435,25 @@
sk = udp_v6_lookup(daddr, uh->dest, saddr, uh->source, dev->ifindex);
- if (sk == NULL) {
- if (net_ratelimit())
- printk(KERN_DEBUG "icmp for unknown sock\n");
+ if (sk == NULL)
return;
- }
- if (icmpv6_err_convert(type, code, &err)) {
- if(sk->bsdism && sk->state!=TCP_ESTABLISHED)
- return;
-
- sk->err = err;
- sk->error_report(sk);
- } else {
- sk->err_soft = err;
- }
+ if (!icmpv6_err_convert(type, code, &err) &&
+ !sk->net_pinfo.af_inet6.recverr)
+ return;
+
+ if (sk->bsdism && sk->state!=TCP_ESTABLISHED)
+ return;
+
+ if (sk->net_pinfo.af_inet6.recverr)
+ ipv6_icmp_error(sk, skb, err, uh->dest, ntohl(info), (u8 *)(uh+1));
+
+ sk->err = err;
+ sk->error_report(sk);
}
static inline int udpv6_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
{
-
if (sock_queue_rcv_skb(sk,skb)<0) {
udp_stats_in6.UdpInErrors++;
ipv6_statistics.Ip6InDiscards++;
@@ -768,6 +757,11 @@
udh.uh.dest = sin6->sin6_port;
daddr = &sin6->sin6_addr;
+
+ /* Otherwise it will be difficult to maintain sk->dst_cache. */
+ if (sk->state == TCP_ESTABLISHED &&
+ !ipv6_addr_cmp(daddr, &sk->net_pinfo.af_inet6.daddr))
+ daddr = &sk->net_pinfo.af_inet6.daddr;
} else {
if (sk->state != TCP_ESTABLISHED)
return(-ENOTCONN);
@@ -785,6 +779,7 @@
sin.sin_addr.s_addr = daddr->s6_addr32[3];
sin.sin_port = udh.uh.dest;
msg->msg_name = (struct sockaddr *)(&sin);
+ msg->msg_namelen = sizeof(sin);
return udp_sendmsg(sk, msg, ulen);
}
@@ -806,7 +801,7 @@
udh.daddr = daddr;
udh.uh.source = sk->sport;
- udh.uh.len = len < 0x1000 ? htons(len) : 0;
+ udh.uh.len = len < 0x10000 ? htons(len) : 0;
udh.uh.check = 0;
udh.iov = msg->msg_iov;
udh.wcheck = 0;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov