[Gd-chatter] r10919 - trunk/libraries/layer
hannes at gwydiondylan.org
hannes at gwydiondylan.org
Tue Oct 3 23:30:33 CEST 2006
Author: hannes
Date: Tue Oct 3 23:30:31 2006
New Revision: 10919
Modified:
trunk/libraries/layer/layer.dylan
Log:
Bug: 7299
*removed locking in find-mac-address, is now handled via outstanding-packets slot,
*when an arp frame arrives, all outstanding-packets will be sent
Modified: trunk/libraries/layer/layer.dylan
==============================================================================
--- trunk/libraries/layer/layer.dylan (original)
+++ trunk/libraries/layer/layer.dylan Tue Oct 3 23:30:31 2006
@@ -131,8 +131,8 @@
define generic v4-address (object :: <ip-over-ethernet-adapter>) => (res :: <ipv4-address>);
define open generic ip-layer (object :: <object>) => (res :: <ip-layer>);
define open generic ip-layer-setter (value :: <ip-layer>, object :: <object>) => (res :: <ip-layer>);
-define open generic ip-send-socket (object :: <ip-over-ethernet-adapter>) => (res :: <ethernet-socket>);
-define open generic ip-send-socket-setter (value :: <ethernet-socket>, object :: <ip-over-ethernet-adapter>) => (res :: <ethernet-socket>);
+define open generic ip-send-socket (object) => (res :: <ethernet-socket>);
+define open generic ip-send-socket-setter (value :: <ethernet-socket>, object) => (res :: <ethernet-socket>);
define open generic netmask (object :: <ip-over-ethernet-adapter>) => (res :: <integer>);
define class <ip-over-ethernet-adapter> (<adapter>)
@@ -145,11 +145,39 @@
end;
define method send (socket :: <ip-over-ethernet-adapter>, destination :: <ipv4-address>, payload :: <container-frame>);
- let destination-mac = find-mac-address(socket.arp-handler, destination);
- if (destination-mac)
- send(socket.ip-send-socket, destination-mac, payload);
+ let arp-entry = element(socket.arp-handler.arp-table, destination, default: #f);
+ if (instance?(arp-entry, <known-arp-entry>))
+ send(socket.ip-send-socket, arp-entry.arp-mac-address, payload);
else
- format-out("Couldn't find mac-address for %=\n", destination);
+ let arp-handler = socket.arp-handler;
+ with-lock(arp-handler.lock)
+ if (arp-entry)
+ arp-entry.outstanding-packets := add!(arp-entry.outstanding-packets, payload);
+ else
+ let from-addr = arp-handler.send-socket.listen-address;
+ let from-ip = find-key(arp-handler.arp-table,
+ method(x)
+ x.arp-mac-address = from-addr
+ end);
+ let arp-request = make(<arp-frame>,
+ operation: 1,
+ source-mac-address: from-addr,
+ source-ip-address: from-ip,
+ target-ip-address: destination,
+ target-mac-address: mac-address("00:00:00:00:00:00"));
+ send(arp-handler.send-socket, $broadcast-ethernet-address, arp-request);
+ let outstanding-request = make(<outstanding-arp-request>,
+ handler: arp-handler,
+ request: arp-request,
+ destination: $broadcast-ethernet-address,
+ ip-address: destination,
+ outstanding-packets: list(payload));
+ let timer* = make(<timer>, in: 5, event: curry(try-again, outstanding-request, arp-handler));
+ outstanding-request.timer := timer*;
+ arp-handler.arp-table[destination] := outstanding-request;
+ arp-entry := outstanding-request;
+ end;
+ end;
end;
end;
@@ -167,6 +195,7 @@
connect(arp-fan-in, ip-over-ethernet.arp-handler);
ip-over-ethernet.arp-handler.send-socket := arp-socket;
+
ip-over-ethernet.arp-handler.arp-table[ip-over-ethernet.v4-address]
:= make(<advertised-arp-entry>,
ip-address: ip-over-ethernet.v4-address,
@@ -178,6 +207,7 @@
#x800,
mac-address: $broadcast-ethernet-address);
ip-over-ethernet.ip-send-socket := ip-socket;
+ ip-over-ethernet.arp-handler.ip-send-socket := ip-socket;
let ipv4-fan-in = make(<fan-in>);
connect(ip-socket.decapsulator, ipv4-fan-in);
connect(ip-broadcast-socket.decapsulator, ipv4-fan-in);
@@ -326,7 +356,7 @@
type: 0,
code: 0,
payload: frame.payload);
- make(<thread>, function: curry(send, node.ip-socket, frame.parent.source-address, response));
+ send(node.ip-socket, frame.parent.source-address, response)
end;
end;
define generic icmp-handler (object :: <icmp-over-ip-adapter>) => (res :: <icmp-handler>);
@@ -350,17 +380,17 @@
constant slot arp-table :: <vector-table> = make(<vector-table>);
constant slot lock :: <lock> = make(<lock>);
slot send-socket :: <socket>;
+ slot ip-send-socket :: <ethernet-socket>;
end;
define generic original-request (object :: <outstanding-arp-request>) => (res :: <frame>);
define generic destination (object :: <outstanding-arp-request>) => (res :: <mac-address>);
-define open generic notification (object :: <outstanding-arp-request>) => (res :: <notification>);
-define open generic notification-setter (value :: <notification>, object :: <outstanding-arp-request>) => (res :: <notification>);
define open generic timer (object :: <outstanding-arp-request>) => (res :: <timer>);
define open generic timer-setter (value :: <timer>, object :: <outstanding-arp-request>) => (res :: <timer>);
define open generic counter (object :: <outstanding-arp-request>) => (res :: <object>);
define open generic counter-setter (value :: <object>, object :: <outstanding-arp-request>) => (res :: <object>);
-
+define open generic outstanding-packets (object :: <outstanding-arp-request>) => (res :: <list>);
+define open generic outstanding-packets-setter (value :: <list>, object :: <outstanding-arp-request>) => (res :: <list>);
define open generic ip-address (object :: <arp-entry>) => (res :: <ipv4-address>);
define abstract class <arp-entry> (<object>)
constant slot ip-address :: <ipv4-address>, required-init-keyword: ip-address:;
@@ -369,9 +399,9 @@
define class <outstanding-arp-request> (<arp-entry>)
constant slot original-request :: <frame>, required-init-keyword: request:;
constant slot destination :: <mac-address>, required-init-keyword: destination:;
- slot notification :: <notification>;
slot timer :: <timer>;
slot counter = 0;
+ slot outstanding-packets :: <list>, required-init-keyword: outstanding-packets:;
end;
define generic arp-mac-address (object :: <known-arp-entry>) => (res :: <mac-address>);
@@ -393,7 +423,7 @@
define method try-again (request :: <outstanding-arp-request>, handler :: <arp-handler>)
with-lock(handler.lock)
if (request.counter > 3)
- release-all(request.notification)
+ remove-key!(arp-handler.arp-table, request.ip-address);
else
send(handler.send-socket, request.destination, request.original-request);
request.timer := make(<timer>, in: 5, event: curry(try-again, request, handler));
@@ -401,11 +431,6 @@
end
end
end;
-
-define method initialize (outstanding-arp-request :: <outstanding-arp-request>,
- #rest rest, #key handler :: <arp-handler>, #all-keys)
- outstanding-arp-request.notification := make(<notification>, lock: handler.lock);
-end;
define method push-data-aux (input :: <push-input>,
node :: <arp-handler>,
@@ -426,7 +451,11 @@
elseif (frame.operation = 2)
with-lock(node.lock)
let old-entry = element(node.arp-table, frame.source-ip-address, default: #f);
- maybe-add-response-to-table(old-entry, node, frame)
+ if (instance?(old-entry, <outstanding-arp-request>))
+ cancel(old-entry.timer);
+ do(curry(send, node.ip-send-socket, frame.source-mac-address), old-entry.outstanding-packets);
+ end;
+ maybe-add-response-to-table(old-entry, node, frame);
end
end;
end;
@@ -440,14 +469,11 @@
define method maybe-add-response-to-table
(old-entry == #f, node :: <arp-handler>, frame :: <arp-frame>)
- add-response-to-table(node, frame)
end;
define method maybe-add-response-to-table
(old-entry :: <outstanding-arp-request>, node :: <arp-handler>, frame :: <arp-frame>)
- cancel(old-entry.timer);
add-response-to-table(node, frame);
- release-all(old-entry.notification);
end;
define method maybe-add-response-to-table
@@ -466,47 +492,6 @@
add-response-to-table(node, frame)
end;
-define method find-mac-address (arp-handler :: <arp-handler>, ip :: <ipv4-address>)
- => (res :: false-or(<mac-address>))
- let arp-entry = element(arp-handler.arp-table, ip, default: #f);
- if (instance?(arp-entry, <known-arp-entry>))
- arp-entry.arp-mac-address;
- else
- with-lock(arp-handler.lock)
- unless(arp-entry)
- let from-addr = arp-handler.send-socket.listen-address;
- let from-ip = find-key(arp-handler.arp-table,
- method(x)
- x.arp-mac-address = from-addr
- end);
- let arp-request = make(<arp-frame>,
- operation: 1,
- source-mac-address: from-addr,
- source-ip-address: from-ip,
- target-ip-address: ip,
- target-mac-address: mac-address("00:00:00:00:00:00"));
- send(arp-handler.send-socket, $broadcast-ethernet-address, arp-request);
- let outstanding-request = make(<outstanding-arp-request>,
- handler: arp-handler,
- request: arp-request,
- destination: $broadcast-ethernet-address,
- ip-address: ip);
- let timer* = make(<timer>, in: 5, event: curry(try-again, outstanding-request, arp-handler));
- outstanding-request.timer := timer*;
- arp-handler.arp-table[ip] := outstanding-request;
- arp-entry := outstanding-request;
- end;
- wait-for(arp-entry.notification);
- let entry = element(arp-handler.arp-table, ip, default: #f);
- if (entry & instance?(entry, <known-arp-entry>))
- entry.arp-mac-address;
- else
- remove-key!(arp-handler.arp-table, ip);
- #f
- end;
- end;
- end;
-end;
begin
@@ -549,7 +534,7 @@
code: 0,
payload: parse-frame(<raw-frame>, as(<byte-vector>, #(#x23, #x42, #x0, #x0)))));
- format-out("Mac 192.168.0.1: %=\n", find-mac-address(arp-handler, ipv4-address("192.168.0.1")));
+ format-out("Mac 192.168.0.1: %=\n", element(arp-handler.arp-table, ipv4-address("192.168.0.1"), default: #f));
sleep(1200);
end;
More information about the chatter
mailing list