|
From: <ljs...@us...> - 2008-04-29 01:12:50
|
Revision: 569
http://cadcdev.svn.sourceforge.net/cadcdev/?rev=569&view=rev
Author: ljsebald
Date: 2008-04-28 18:12:32 -0700 (Mon, 28 Apr 2008)
Log Message:
-----------
Changing the behavior when a send is attempted to a host that does not have a cached ARP entry. Now, net_arp_lookup will return -2, signaling that an ARP query has been sent out. net_ipv4_send_packet detects this condition and returns this to the caller (net_udp_send_raw at this point). net_udp_send_raw sees this condition returned from net_ipv4_send_packet, and retries the transmission after 100ms. Thus, the first send to hosts won't fail in UDP any more, unless the host does not respond to the ARP query (i.e. its not actually there).
Modified Paths:
--------------
kos/kernel/net/net_arp.c
kos/kernel/net/net_ipv4.c
kos/kernel/net/net_udp.c
kos/kernel/net/net_udp.h
Modified: kos/kernel/net/net_arp.c
===================================================================
--- kos/kernel/net/net_arp.c 2008-04-29 00:48:20 UTC (rev 568)
+++ kos/kernel/net/net_arp.c 2008-04-29 01:12:32 UTC (rev 569)
@@ -122,7 +122,7 @@
net_arp_query(nif, ip_in);
/* Return failure */
- return -1;
+ return -2;
}
/* Do a reverse ARP lookup: look for an IP for a given mac address; note
Modified: kos/kernel/net/net_ipv4.c
===================================================================
--- kos/kernel/net/net_ipv4.c 2008-04-29 00:48:20 UTC (rev 568)
+++ kos/kernel/net/net_ipv4.c 2008-04-29 01:12:32 UTC (rev 569)
@@ -80,6 +80,7 @@
uint8 dest_mac[6];
uint8 pkt[size + sizeof(ip_hdr_t) + sizeof(eth_hdr_t)];
eth_hdr_t *ehdr;
+ int err;
if(net == NULL) {
net = net_default_dev;
@@ -104,11 +105,17 @@
memcpy(dest_ip, net->gateway, 4);
}
- /* Get our destination's MAC address */
- if(net_arp_lookup(net, dest_ip, dest_mac) == -1) {
+ /* Get our destination's MAC address. If we do not have the MAC address
+ cached, return a distinguished error to the upper-level protocol so
+ that it can decide what to do. */
+ err = net_arp_lookup(net, dest_ip, dest_mac);
+ if(err == -1) {
errno = ENETUNREACH;
return -1;
}
+ else if(err == -2) {
+ return -2;
+ }
/* Fill in the ethernet header */
ehdr = (eth_hdr_t *)pkt;
Modified: kos/kernel/net/net_udp.c
===================================================================
--- kos/kernel/net/net_udp.c 2008-04-29 00:48:20 UTC (rev 568)
+++ kos/kernel/net/net_udp.c 2008-04-29 01:12:32 UTC (rev 569)
@@ -399,7 +399,7 @@
udpsock->local_addr.sin_port,
udpsock->remote_addr.sin_addr.s_addr,
udpsock->remote_addr.sin_port, (uint8 *) message,
- length);
+ length, udpsock->flags);
}
ssize_t net_udp_sendto(net_socket_t *hnd, const void *message, size_t length,
@@ -463,7 +463,7 @@
return net_udp_send_raw(NULL, udpsock->local_addr.sin_addr.s_addr,
udpsock->local_addr.sin_port,
realaddr->sin_addr.s_addr, realaddr->sin_port,
- (uint8 *) message, length);
+ (uint8 *) message, length, udpsock->flags);
}
int net_udp_shutdownsock(net_socket_t *hnd, int how) {
@@ -671,9 +671,10 @@
int net_udp_send_raw(netif_t *net, uint32 src_ip, uint16 src_port,
uint32 dst_ip, uint16 dst_port, const uint8 *data,
- int size) {
+ int size, int flags) {
uint8 buf[size + 12 + sizeof(udp_hdr_t)];
ip_pseudo_hdr_t *ps = (ip_pseudo_hdr_t *) buf;
+ int err;
if(net == NULL && net_default_dev == NULL) {
errno = ENETDOWN;
@@ -705,12 +706,25 @@
ps->checksum = 0;
ps->checksum = net_ipv4_checksum(buf, size + 12);
+retry_send:
/* Pass everything off to the network layer to do the rest. */
- if(net_ipv4_send(net, buf + 12, size, 0, 64, IPPROTO_UDP, ps->src_addr,
- ps->dst_addr)) {
- /* If the packet send fails, errno will be set already. */
+ err = net_ipv4_send(net, buf + 12, size, 0, 64, IPPROTO_UDP, ps->src_addr,
+ ps->dst_addr);
+
+ /* If the IP layer returns that the ARP cache didn't have the entry for the
+ destination, sleep for a little bit, and try again (as long as the
+ non-blocking flag was not set). */
+ if(err == -2 && !(flags & O_NONBLOCK)) {
+ thd_sleep(100);
+ goto retry_send;
+ }
+ else if(err == -2) {
+ errno = ENETUNREACH;
return -1;
}
+ else if(err < 0) {
+ return -1;
+ }
else {
return size - sizeof(udp_hdr_t);
}
Modified: kos/kernel/net/net_udp.h
===================================================================
--- kos/kernel/net/net_udp.h 2008-04-29 00:48:20 UTC (rev 568)
+++ kos/kernel/net/net_udp.h 2008-04-29 01:12:32 UTC (rev 569)
@@ -1,7 +1,7 @@
/* KallistiOS ##version##
kernel/net/net_udp.h
- Copyright (C) 2005, 2006, 2007 Lawrence Sebald
+ Copyright (C) 2005, 2006, 2007, 2008 Lawrence Sebald
*/
@@ -23,7 +23,7 @@
int net_udp_input(netif_t *src, ip_hdr_t *ih, const uint8 *data, int size);
int net_udp_send_raw(netif_t *net, uint32 src_ip, uint16 src_port,
uint32 dst_ip, uint16 dst_port, const uint8 *data,
- int size);
+ int size, int flags);
/* Sockets */
int net_udp_accept(net_socket_t *hnd, struct sockaddr *addr,
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|