Skip to content

Commit

Permalink
bug workaround: the TCP stack does not retransmit unless it receives …
Browse files Browse the repository at this point in the history
…some more packets. Add a timer to check for any retransmits 2 seconds after receiving any packet.
  • Loading branch information
smbz committed Sep 14, 2011
1 parent 7922bce commit bc87aac
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 12 deletions.
2 changes: 1 addition & 1 deletion TCPStack.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ class TCPConnection():
"""Manages the state of one half of a TCP connection."""
def __init__(self, syn_seq, my_ip, my_port, other_ip, other_port,
connection_over_callback, has_data_to_send_callback,
assumed_rtt=0.5, mtu=1500, max_data=2048, max_wait_time_sec=5):
assumed_rtt=0.5, mtu=1500, max_data=2048, max_wait_time_sec=30):
# socket pair
self.my_ip = my_ip
self.my_port = my_port
Expand Down
34 changes: 23 additions & 11 deletions Topology.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@

from django.contrib.auth.models import User

from twisted.internet import reactor

from settings import ARP_CACHE_TIMEOUT, MAY_FORWARD_TO_PRIVATE_IPS, WEB_SERVER_ROOT_WWW
from AddressAllocation import allocate_to_topology
from DRRQueue import DRRQueue
Expand Down Expand Up @@ -256,7 +258,7 @@ def handle_packet_from_client(self, conn, pkt_msg):

# failed to find the specified interface
fmt = 'bad packet request: invalid interface: %s'
return fmt % (n.name, departure_intf_name)
return fmt % ((n.name, departure_intf_name),)

def create_job_for_incoming_packet(self, packet, rewrite_dst_mac):
"""Enqueues a job for handling this packet with handle_incoming_packet()."""
Expand Down Expand Up @@ -909,6 +911,8 @@ class WebServer(BasicNode):
def __init__(self, topo, name, path_to_serve):
BasicNode.__init__(self, topo, name)
self.http_server = HTTPServer(TCPServer.ANY_PORT, path_to_serve)
self.intf = None
self.pkt = None

@staticmethod
def get_type_str():
Expand All @@ -917,24 +921,32 @@ def get_type_str():
def handle_non_icmp_ip_packet_to_self(self, intf, pkt):
"""If pkt is to an HTTP_PORT, then the packet is handed off to the HTTP
server. Otherwise, the default superclass implementation is called."""
reactor.callLater(2, self.send_packets)
if pkt.is_valid_tcp():
if is_http_port(pkt.tcp_dst_port):
self.handle_http_request(intf, pkt)
return
BasicNode.handle_non_icmp_ip_packet_to_self(self, intf, pkt)

def handle_http_request(self, intf, pkt):
"""Forward the received packet from an HTTP client to the web server."""
"""Forward the rceived packet from an HTTP client to the web server."""
self.intf = intf
self.pkt = pkt
tcp_conn = self.http_server.handle_tcp(pkt)
if tcp_conn:
tcp_pts = tcp_conn.get_packets_to_send()
if tcp_pts:
for tcp, data in tcp_pts:
eth = pkt.get_reversed_eth()
ip = pkt.get_reversed_ip(new_ttl=64, new_tlen=pkt.ip_hlen+len(tcp)+len(data))
pkt_out = eth + ip + Packet.cksum_tcp_hdr(ip, tcp, data) + data
logging.debug('%s sending packet from HTTP server: %s' % (self, pktstr(pkt_out)))
intf.link.send_to_other(intf, pkt_out)
self.send_packets()

def send_packets(self):
"""Send any waiting packets"""
if self.intf and self.pkt:
for (_, tcp_conn) in self.http_server.connections.iteritems():
if tcp_conn and not tcp_conn.dead:
tcp_pts = tcp_conn.get_packets_to_send()
for tcp, data in tcp_pts:
eth = self.pkt.get_reversed_eth()
ip = self.pkt.get_reversed_ip(new_ttl=64, new_tlen=self.pkt.ip_hlen+len(tcp)+len(data))
pkt_out = eth + ip + Packet.cksum_tcp_hdr(ip, tcp, data) + data
logging.debug('%s sending packet from HTTP server: %s' % (self, pktstr(pkt_out)))
self.intf.link.send_to_other(self.intf, pkt_out)

def __str__(self):
ps = ' serving:%s' % self.http_server.get_path_being_served()
Expand Down

0 comments on commit bc87aac

Please sign in to comment.