--- a/src/internet-node/ipv4-end-point-demux.cc Fri Mar 14 16:36:55 2008 -0700
+++ b/src/internet-node/ipv4-end-point-demux.cc Fri Mar 14 16:37:02 2008 -0700
@@ -83,14 +83,14 @@
NS_LOG_WARN ("Ephemeral port allocation failed.");
return 0;
}
- Ipv4EndPoint *endPoint = new Ipv4EndPoint (Ipv4Address::GetAny (), port, Ipv4Address::GetAny ());
+ Ipv4EndPoint *endPoint = new Ipv4EndPoint (Ipv4Address::GetAny (), port);
m_endPoints.push_back (endPoint);
NS_LOG_DEBUG ("Now have >>" << m_endPoints.size () << "<< endpoints.");
return endPoint;
}
Ipv4EndPoint *
-Ipv4EndPointDemux::Allocate (Ipv4Address address, Ipv4Address localInterface)
+Ipv4EndPointDemux::Allocate (Ipv4Address address)
{
NS_LOG_FUNCTION;
NS_LOG_PARAMS (this << address);
@@ -100,7 +100,7 @@
NS_LOG_WARN ("Ephemeral port allocation failed.");
return 0;
}
- Ipv4EndPoint *endPoint = new Ipv4EndPoint (address, port, localInterface);
+ Ipv4EndPoint *endPoint = new Ipv4EndPoint (address, port);
m_endPoints.push_back (endPoint);
NS_LOG_DEBUG ("Now have >>" << m_endPoints.size () << "<< endpoints.");
return endPoint;
@@ -112,20 +112,20 @@
NS_LOG_FUNCTION;
NS_LOG_PARAMS (this << port);
- return Allocate (Ipv4Address::GetAny (), port, Ipv4Address::GetAny ());
+ return Allocate (Ipv4Address::GetAny (), port);
}
Ipv4EndPoint *
-Ipv4EndPointDemux::Allocate (Ipv4Address address, uint16_t port, Ipv4Address localInterface)
+Ipv4EndPointDemux::Allocate (Ipv4Address address, uint16_t port)
{
NS_LOG_FUNCTION;
- NS_LOG_PARAMS (this << address << port << localInterface);
+ NS_LOG_PARAMS (this << address << port);
if (LookupLocal (address, port))
{
NS_LOG_WARN ("Duplicate address/port; failing.");
return 0;
}
- Ipv4EndPoint *endPoint = new Ipv4EndPoint (address, port, localInterface);
+ Ipv4EndPoint *endPoint = new Ipv4EndPoint (address, port);
m_endPoints.push_back (endPoint);
NS_LOG_DEBUG ("Now have >>" << m_endPoints.size () << "<< endpoints.");
return endPoint;
@@ -133,8 +133,7 @@
Ipv4EndPoint *
Ipv4EndPointDemux::Allocate (Ipv4Address localAddress, uint16_t localPort,
- Ipv4Address peerAddress, uint16_t peerPort,
- Ipv4Address localInterface)
+ Ipv4Address peerAddress, uint16_t peerPort)
{
NS_LOG_FUNCTION;
NS_LOG_PARAMS (this << localAddress << localPort << peerAddress << peerPort);
@@ -150,7 +149,7 @@
return 0;
}
}
- Ipv4EndPoint *endPoint = new Ipv4EndPoint (localAddress, localPort, localInterface);
+ Ipv4EndPoint *endPoint = new Ipv4EndPoint (localAddress, localPort);
endPoint->SetPeer (peerAddress, peerPort);
m_endPoints.push_back (endPoint);
@@ -185,10 +184,11 @@
Ptr<Ipv4Interface> incomingInterface)
{
NS_LOG_FUNCTION;
- uint32_t genericity = 3;
- Ipv4EndPoint *generic = 0;
- EndPoints retval;
-
+ EndPoints retval1; // Matches exact on local port, wildcards on others
+ EndPoints retval2; // Matches exact on local port/adder, wildcards on others
+ EndPoints retval3; // Matches all but local address
+ EndPoints retval4; // Exact match on all 4
+
//NS_LOG_PARAMS (this << daddr << dport << saddr << sport);
NS_LOG_PARAMS_BEGIN ();
NS_LOG_PARAM (this);
@@ -198,79 +198,88 @@
NS_LOG_PARAM (sport);
NS_LOG_PARAM (incomingInterface);
NS_LOG_PARAMS_END ();
-
+ NS_LOG_DEBUG ("Looking up endpoint for destination address " << daddr);
for (EndPointsI i = m_endPoints.begin (); i != m_endPoints.end (); i++)
{
- NS_LOG_DEBUG ("Looking at endpoint dport=" << (*i)->GetLocalPort ()
- << " daddr=" << (*i)->GetLocalAddress ()
- << " sport=" << (*i)->GetPeerPort ()
- << " saddr=" << (*i)->GetPeerAddress ());
- if ((*i)->GetLocalPort () != dport)
+ Ipv4EndPoint* endP = *i;
+ NS_LOG_DEBUG ("Looking at endpoint dport=" << endP->GetLocalPort ()
+ << " daddr=" << endP->GetLocalAddress ()
+ << " sport=" << endP->GetPeerPort ()
+ << " saddr=" << endP->GetPeerAddress ());
+ if (endP->GetLocalPort () != dport)
{
- NS_LOG_LOGIC ("Skipping endpoint " << &(*i)
+ NS_LOG_LOGIC ("Skipping endpoint " << &endP
<< " because endpoint dport "
- << (*i)->GetLocalPort ()
+ << endP->GetLocalPort ()
<< " does not match packet dport " << dport);
continue;
}
- bool isBroadcast =
- (daddr.IsBroadcast () ||
- daddr.IsSubnetDirectedBroadcast (incomingInterface->GetNetworkMask ()));
+ bool isBroadcast = (daddr.IsBroadcast () ||
+ daddr.IsSubnetDirectedBroadcast (
+ incomingInterface->GetNetworkMask ()));
Ipv4Address incomingInterfaceAddr = incomingInterface->GetAddress ();
+ NS_LOG_DEBUG ("dest addr " << daddr << " broadcast? " << isBroadcast);
+ bool localAddressMatchesWildCard =
+ endP->GetLocalAddress() == Ipv4Address::GetAny();
+ bool localAddressMatchesExact = endP->GetLocalAddress () == daddr;
- NS_LOG_DEBUG ("dest addr " << daddr << " broadcast? " << isBroadcast
- << " localInterface="<< (*i)->GetLocalInterface ());
- bool localAddressMatches;
if (isBroadcast)
{
- if ((*i)->GetLocalInterface () == Ipv4Address::GetAny ())
- {
- localAddressMatches = true;
- }
- else
- {
- localAddressMatches = ((*i)->GetLocalInterface () == incomingInterfaceAddr);
- }
+ NS_LOG_DEBUG("Found bcast, localaddr " << endP->GetLocalAddress());
+ }
+
+ if (isBroadcast && (endP->GetLocalAddress() != Ipv4Address::GetAny()))
+ {
+ localAddressMatchesExact = (endP->GetLocalAddress () ==
+ incomingInterfaceAddr);
}
- else
- {
- localAddressMatches = ((*i)->GetLocalAddress () == daddr);
- }
- NS_LOG_LOGIC ("Local address matches: " << localAddressMatches);
- NS_LOG_LOGIC ("Peer port matches: " <<
- bool ((*i)->GetPeerPort () == sport || (*i)->GetPeerPort () == 0));
- NS_LOG_LOGIC ("Peer address matches: " <<
- bool ((*i)->GetPeerAddress () == saddr ||
- (*i)->GetPeerAddress () == Ipv4Address::GetAny ()));
+ // if no match here, keep looking
+ if (!(localAddressMatchesExact || localAddressMatchesWildCard))
+ continue;
+ bool remotePeerMatchesExact = endP->GetPeerPort () == sport;
+ bool remotePeerMatchesWildCard = endP->GetPeerPort() == 0;
+ bool remoteAddressMatchesExact = endP->GetPeerAddress () == saddr;
+ bool remoteAddressMatchesWildCard = endP->GetPeerAddress () ==
+ Ipv4Address::GetAny();
+ // If remote does not match either with exact or wildcard,
+ // skip this one
+ if (!(remotePeerMatchesExact || remotePeerMatchesWildCard))
+ continue;
+ if (!(remoteAddressMatchesExact || remoteAddressMatchesWildCard))
+ continue;
- if ( localAddressMatches
- && ((*i)->GetPeerPort () == sport || (*i)->GetPeerPort () == 0)
- && ((*i)->GetPeerAddress () == saddr || (*i)->GetPeerAddress () == Ipv4Address::GetAny ()))
- {
- NS_LOG_LOGIC ("MATCH");
- /* this is an exact match. */
- retval.push_back (*i);
+ // Now figure out which return list to add this one to
+ if (localAddressMatchesWildCard &&
+ remotePeerMatchesWildCard &&
+ remoteAddressMatchesWildCard)
+ { // Only local port matches exactly
+ retval1.push_back(endP);
}
- uint32_t tmp = 0;
- if ((*i)->GetLocalAddress () == Ipv4Address::GetAny ())
- {
- tmp ++;
+ if ((localAddressMatchesExact || (isBroadcast && localAddressMatchesWildCard))&&
+ remotePeerMatchesWildCard &&
+ remoteAddressMatchesWildCard)
+ { // Only local port and local address matches exactly
+ retval2.push_back(endP);
}
- if ((*i)->GetPeerAddress () == Ipv4Address::GetAny ())
- {
- tmp ++;
+ if (localAddressMatchesWildCard &&
+ remotePeerMatchesExact &&
+ remoteAddressMatchesExact)
+ { // All but local address
+ retval3.push_back(endP);
}
- if (tmp < genericity)
- {
- generic = (*i);
- genericity = tmp;
+ if (localAddressMatchesExact &&
+ remotePeerMatchesExact &&
+ remoteAddressMatchesExact)
+ { // All 4 match
+ retval4.push_back(endP);
}
}
- if (retval.size () == 0 && generic != 0)
- {
- retval.push_back (generic);
- }
- return retval;
+
+ // Here we find the most exact match
+ if (!retval4.empty()) return retval4;
+ if (!retval3.empty()) return retval3;
+ if (!retval2.empty()) return retval2;
+ return retval1; // might be empty if no matches
}
uint16_t
--- a/src/internet-node/ipv4-end-point-demux.h Fri Mar 14 16:36:55 2008 -0700
+++ b/src/internet-node/ipv4-end-point-demux.h Fri Mar 14 16:37:02 2008 -0700
@@ -48,13 +48,13 @@
Ptr<Ipv4Interface> incomingInterface);
Ipv4EndPoint *Allocate (void);
- Ipv4EndPoint *Allocate (Ipv4Address address, Ipv4Address localInterface);
+ Ipv4EndPoint *Allocate (Ipv4Address address);
Ipv4EndPoint *Allocate (uint16_t port);
- Ipv4EndPoint *Allocate (Ipv4Address address, uint16_t port, Ipv4Address localInterface);
+ Ipv4EndPoint *Allocate (Ipv4Address address, uint16_t port);
Ipv4EndPoint *Allocate (Ipv4Address localAddress,
uint16_t localPort,
Ipv4Address peerAddress,
- uint16_t peerPort, Ipv4Address localInterface);
+ uint16_t peerPort);
void DeAllocate (Ipv4EndPoint *endPoint);
--- a/src/internet-node/ipv4-end-point.cc Fri Mar 14 16:36:55 2008 -0700
+++ b/src/internet-node/ipv4-end-point.cc Fri Mar 14 16:37:02 2008 -0700
@@ -24,12 +24,11 @@
namespace ns3 {
-Ipv4EndPoint::Ipv4EndPoint (Ipv4Address address, uint16_t port, Ipv4Address localInterface)
+Ipv4EndPoint::Ipv4EndPoint (Ipv4Address address, uint16_t port)
: m_localAddr (address),
m_localPort (port),
m_peerAddr (Ipv4Address::GetAny ()),
- m_peerPort (0),
- m_localInterface (localInterface)
+ m_peerPort (0)
{}
Ipv4EndPoint::~Ipv4EndPoint ()
{
@@ -51,17 +50,6 @@
m_localAddr = address;
}
-Ipv4Address Ipv4EndPoint::GetLocalInterface (void) const
-{
- return m_localInterface;
-}
-
-void
-Ipv4EndPoint::SetLocalInterface (Ipv4Address localInterface)
-{
- m_localInterface = localInterface;
-}
-
uint16_t
Ipv4EndPoint::GetLocalPort (void)
{
--- a/src/internet-node/ipv4-end-point.h Fri Mar 14 16:36:55 2008 -0700
+++ b/src/internet-node/ipv4-end-point.h Fri Mar 14 16:37:02 2008 -0700
@@ -33,7 +33,7 @@
class Ipv4EndPoint {
public:
- Ipv4EndPoint (Ipv4Address address, uint16_t port, Ipv4Address localInterface);
+ Ipv4EndPoint (Ipv4Address address, uint16_t port);
~Ipv4EndPoint ();
Ipv4Address GetLocalAddress (void);
@@ -41,8 +41,6 @@
uint16_t GetLocalPort (void);
Ipv4Address GetPeerAddress (void);
uint16_t GetPeerPort (void);
- Ipv4Address GetLocalInterface (void) const;
- void SetLocalInterface (Ipv4Address localInterface);
void SetPeer (Ipv4Address address, uint16_t port);
@@ -58,11 +56,6 @@
uint16_t m_peerPort;
Callback<void,Ptr<Packet>, Ipv4Address, uint16_t> m_rxCallback;
Callback<void> m_destroyCallback;
-
- // If the corresponding socket is bound to a specific local
- // interface, m_localInterface contains that interface's ipv4
- // address, else it contains the value Ipv4Address::GetAny ().
- Ipv4Address m_localInterface;
};
}; // namespace ns3
--- a/src/internet-node/rtt-estimator.cc Fri Mar 14 16:36:55 2008 -0700
+++ b/src/internet-node/rtt-estimator.cc Fri Mar 14 16:37:02 2008 -0700
@@ -221,9 +221,9 @@
return (est + Scalar (4) * variance) * Scalar (multiplier); // As suggested by Jacobson
}
-RttEstimator* RttMeanDeviation::Copy () const
+Ptr<RttEstimator> RttMeanDeviation::Copy () const
{
- return new RttMeanDeviation (*this);
+ return Create<RttMeanDeviation> (*this);
}
void RttMeanDeviation::Reset ()
--- a/src/internet-node/rtt-estimator.h Fri Mar 14 16:36:55 2008 -0700
+++ b/src/internet-node/rtt-estimator.h Fri Mar 14 16:37:02 2008 -0700
@@ -62,7 +62,7 @@
virtual Time Estimate() = 0;
virtual Time RetransmitTimeout() = 0;
void Init(SequenceNumber s) { next = s;}
- virtual RttEstimator* Copy() const = 0;
+ virtual Ptr<RttEstimator> Copy() const = 0;
virtual void IncreaseMultiplier();
virtual void ResetMultiplier();
virtual void Reset();
@@ -100,7 +100,7 @@
Time Estimate () { return est;}
Time Variance () { return variance;}
Time RetransmitTimeout ();
- RttEstimator* Copy () const;
+ Ptr<RttEstimator> Copy () const;
void Reset ();
void Gain (double g) { gain = g;}
--- a/src/internet-node/tcp-l4-protocol.cc Fri Mar 14 16:36:55 2008 -0700
+++ b/src/internet-node/tcp-l4-protocol.cc Fri Mar 14 16:37:02 2008 -0700
@@ -36,6 +36,7 @@
#include <vector>
#include <sstream>
+#include <iomanip>
NS_LOG_COMPONENT_DEFINE ("TcpL4Protocol");
@@ -78,7 +79,7 @@
aT[LISTEN][APP_CLOSE] = SA (CLOSED, NO_ACT);
aT[LISTEN][TIMEOUT] = SA (LISTEN, NO_ACT);
aT[LISTEN][ACK_RX] = SA (LISTEN, NO_ACT);
- aT[LISTEN][SYN_RX] = SA (SYN_RCVD, SYN_ACK_TX); //XXX hacked for now, should stay in listen and replicate
+ aT[LISTEN][SYN_RX] = SA (LISTEN, SYN_ACK_TX);//stay in listen and fork
aT[LISTEN][SYN_ACK_RX] = SA (LISTEN, NO_ACT);
aT[LISTEN][FIN_RX] = SA (LISTEN, NO_ACT);
aT[LISTEN][FIN_ACK_RX] = SA (LISTEN, NO_ACT);
@@ -179,7 +180,7 @@
aT[FIN_WAIT_2][APP_LISTEN] = SA (CLOSED, RST_TX);
aT[FIN_WAIT_2][APP_CONNECT] = SA (CLOSED, RST_TX);
aT[FIN_WAIT_2][APP_SEND] = SA (CLOSED, RST_TX);
- aT[FIN_WAIT_2][SEQ_RECV] = SA (FIN_WAIT_2, NO_ACT);
+ aT[FIN_WAIT_2][SEQ_RECV] = SA (FIN_WAIT_2, NEW_SEQ_RX);
aT[FIN_WAIT_2][APP_CLOSE] = SA (FIN_WAIT_2, NO_ACT);
aT[FIN_WAIT_2][TIMEOUT] = SA (FIN_WAIT_2, NO_ACT);
aT[FIN_WAIT_2][ACK_RX] = SA (FIN_WAIT_2, NEW_ACK);
@@ -395,11 +396,11 @@
}
Ipv4EndPoint *
-TcpL4Protocol::Allocate (Ipv4Address address, Ipv4Address localInterface)
+TcpL4Protocol::Allocate (Ipv4Address address)
{
NS_LOG_FUNCTION;
NS_LOG_PARAMS (this << address);
- return m_endPoints->Allocate (address, localInterface);
+ return m_endPoints->Allocate (address);
}
Ipv4EndPoint *
@@ -411,23 +412,21 @@
}
Ipv4EndPoint *
-TcpL4Protocol::Allocate (Ipv4Address address, uint16_t port, Ipv4Address localInterface)
+TcpL4Protocol::Allocate (Ipv4Address address, uint16_t port)
{
NS_LOG_FUNCTION;
NS_LOG_PARAMS (this << address << port);
- return m_endPoints->Allocate (address, port, localInterface);
+ return m_endPoints->Allocate (address, port);
}
Ipv4EndPoint *
TcpL4Protocol::Allocate (Ipv4Address localAddress, uint16_t localPort,
- Ipv4Address peerAddress, uint16_t peerPort,
- Ipv4Address localInterface)
+ Ipv4Address peerAddress, uint16_t peerPort)
{
NS_LOG_FUNCTION;
NS_LOG_PARAMS (this << localAddress << localPort << peerAddress << peerPort);
return m_endPoints->Allocate (localAddress, localPort,
- peerAddress, peerPort,
- localInterface);
+ peerAddress, peerPort);
}
void
@@ -450,6 +449,11 @@
TcpHeader tcpHeader;
//these two do a peek, so that the packet can be forwarded up
packet->RemoveHeader (tcpHeader);
+ NS_LOG_LOGIC("TcpL4Protocol " << this
+ << " receiving seq " << tcpHeader.GetSequenceNumber()
+ << " ack " << tcpHeader.GetAckNumber()
+ << " flags "<< std::hex << (int)tcpHeader.GetFlags() << std::dec
+ << " data size " << packet->GetSize());
packet->AddHeader (tcpHeader);
NS_LOG_LOGIC ("TcpL4Protocol "<<this<<" received a packet");
Ipv4EndPointDemux::EndPoints endPoints =
@@ -465,13 +469,11 @@
source.Print (oss);
oss<<" source port: "<<tcpHeader.GetSourcePort ();
NS_LOG_LOGIC (oss.str ());
+ return;
}
- for (Ipv4EndPointDemux::EndPointsI endPoint = endPoints.begin ();
- endPoint != endPoints.end (); endPoint++)
- {
- NS_LOG_LOGIC ("TcpL4Protocol "<<this<<" forwarding up to endpoint/socket");
- (*endPoint)->ForwardUp (packet, source, tcpHeader.GetSourcePort ());
- }
+ NS_ASSERT_MSG (endPoints.size() == 1 , "Demux returned more than one endpoint");
+ NS_LOG_LOGIC ("TcpL4Protocol "<<this<<" forwarding up to endpoint/socket");
+ (*endPoints.begin ())->ForwardUp (packet, source, tcpHeader.GetSourcePort ());
}
void
@@ -505,6 +507,11 @@
TcpL4Protocol::SendPacket (Ptr<Packet> packet, TcpHeader outgoingHeader,
Ipv4Address saddr, Ipv4Address daddr)
{
+ NS_LOG_LOGIC("TcpL4Protocol " << this
+ << " sending seq " << outgoingHeader.GetSequenceNumber()
+ << " ack " << outgoingHeader.GetAckNumber()
+ << " flags " << std::hex << (int)outgoingHeader.GetFlags() << std::dec
+ << " data size " << packet->GetSize());
NS_LOG_FUNCTION;
NS_LOG_PARAMS (this << packet << saddr << daddr);
// XXX outgoingHeader cannot be logged
--- a/src/internet-node/tcp-l4-protocol.h Fri Mar 14 16:36:55 2008 -0700
+++ b/src/internet-node/tcp-l4-protocol.h Fri Mar 14 16:37:02 2008 -0700
@@ -65,12 +65,11 @@
Ptr<Socket> CreateSocket (void);
Ipv4EndPoint *Allocate (void);
- Ipv4EndPoint *Allocate (Ipv4Address address, Ipv4Address localInterface);
+ Ipv4EndPoint *Allocate (Ipv4Address address);
Ipv4EndPoint *Allocate (uint16_t port);
- Ipv4EndPoint *Allocate (Ipv4Address address, uint16_t port, Ipv4Address localInterface);
+ Ipv4EndPoint *Allocate (Ipv4Address address, uint16_t port);
Ipv4EndPoint *Allocate (Ipv4Address localAddress, uint16_t localPort,
- Ipv4Address peerAddress, uint16_t peerPort,
- Ipv4Address localInterface);
+ Ipv4Address peerAddress, uint16_t peerPort);
void DeAllocate (Ipv4EndPoint *endPoint);
--- a/src/internet-node/tcp-socket.cc Fri Mar 14 16:36:55 2008 -0700
+++ b/src/internet-node/tcp-socket.cc Fri Mar 14 16:37:02 2008 -0700
@@ -69,6 +69,59 @@
}
+TcpSocket::TcpSocket(const TcpSocket& sock)
+ : Socket(sock), //copy the base class callbacks
+ m_skipRetxResched (sock.m_skipRetxResched),
+ m_dupAckCount (sock.m_dupAckCount),
+ m_endPoint (0),
+ m_node (sock.m_node),
+ m_tcp (sock.m_tcp),
+ m_remoteAddress (sock.m_remoteAddress),
+ m_remotePort (sock.m_remotePort),
+ m_localAddress (sock.m_localAddress),
+ m_localPort (sock.m_localPort),
+ m_errno (sock.m_errno),
+ m_shutdownSend (sock.m_shutdownSend),
+ m_shutdownRecv (sock.m_shutdownRecv),
+ m_connected (sock.m_connected),
+ m_state (sock.m_state),
+ m_closeNotified (sock.m_closeNotified),
+ m_closeRequestNotified (sock.m_closeRequestNotified),
+ m_closeOnEmpty (sock.m_closeOnEmpty),
+ m_pendingClose (sock.m_pendingClose),
+ m_nextTxSequence (sock.m_nextTxSequence),
+ m_highTxMark (sock.m_highTxMark),
+ m_highestRxAck (sock.m_highestRxAck),
+ m_lastRxAck (sock.m_lastRxAck),
+ m_nextRxSequence (sock.m_nextRxSequence),
+ m_pendingData (0),
+ m_segmentSize (sock.m_segmentSize),
+ m_rxWindowSize (sock.m_rxWindowSize),
+ m_advertisedWindowSize (sock.m_advertisedWindowSize),
+ m_cWnd (sock.m_cWnd),
+ m_ssThresh (sock.m_ssThresh),
+ m_initialCWnd (sock.m_initialCWnd),
+ m_rtt (0),
+ m_lastMeasuredRtt (Seconds(0.0)),
+ m_cnTimeout (sock.m_cnTimeout),
+ m_cnCount (sock.m_cnCount)
+{
+ NS_LOG_FUNCTION;
+ NS_LOG_LOGIC("Invoked the copy constructor");
+ //copy the pending data if necessary
+ if(sock.m_pendingData)
+ {
+ m_pendingData = sock.m_pendingData->Copy();
+ }
+ //copy the rtt if necessary
+ if (sock.m_rtt)
+ {
+ m_rtt = sock.m_rtt->Copy();
+ }
+ //can't "copy" the endpoint just yes, must do this when we know the peer info
+ //too; this is in SYN_ACK_TX
+}
+
TcpSocket::~TcpSocket ()
{
NS_LOG_FUNCTION;
@@ -153,6 +206,8 @@
}
m_endPoint->SetRxCallback (MakeCallback (&TcpSocket::ForwardUp, this));
m_endPoint->SetDestroyCallback (MakeCallback (&TcpSocket::Destroy, this));
+ m_localAddress = m_endPoint->GetLocalAddress ();
+ m_localPort = m_endPoint->GetLocalPort ();
return 0;
}
@@ -175,14 +230,6 @@
InetSocketAddress transport = InetSocketAddress::ConvertFrom (address);
Ipv4Address ipv4 = transport.GetIpv4 ();
uint16_t port = transport.GetPort ();
- Ipv4Address localInterface = Ipv4Address::GetAny ();
- if (ipv4 != Ipv4Address::GetAny ())
- {
- Ptr<Ipv4> ipv4_api = m_node->GetObject<Ipv4> ();
- // Assert that the given address matches an existing local interface
- NS_ASSERT (ipv4_api->FindInterfaceForAddr (ipv4) != 0);
- localInterface = ipv4;
- }
if (ipv4 == Ipv4Address::GetAny () && port == 0)
{
m_endPoint = m_tcp->Allocate ();
@@ -195,12 +242,12 @@
}
else if (ipv4 != Ipv4Address::GetAny () && port == 0)
{
- m_endPoint = m_tcp->Allocate (ipv4, localInterface);
+ m_endPoint = m_tcp->Allocate (ipv4);
NS_LOG_LOGIC ("TcpSocket "<<this<<" got an endpoint: "<<m_endPoint);
}
else if (ipv4 != Ipv4Address::GetAny () && port != 0)
{
- m_endPoint = m_tcp->Allocate (ipv4, port, localInterface);
+ m_endPoint = m_tcp->Allocate (ipv4, port);
NS_LOG_LOGIC ("TcpSocket "<<this<<" got an endpoint: "<<m_endPoint);
}
@@ -230,15 +277,15 @@
{
return -1;
}
+ if (m_pendingData && m_pendingData->Size() != 0)
+ { // App close with pending data must wait until all data transmitted
+ m_closeOnEmpty = true;
+ NS_LOG_LOGIC("Socket " << this <<
+ " deferring close, state " << m_state);
+ return 0;
+ }
+
Actions_t action = ProcessEvent (APP_CLOSE);
- if (m_pendingData)
- {
- if (action == FIN_TX && m_pendingData->Size () != 0 )
- {
- m_closeOnEmpty = true;
- return 0;
- }
- }
ProcessAction (action);
ShutdownSend ();
return 0;
@@ -259,13 +306,13 @@
NS_ASSERT (m_endPoint != 0);
}
InetSocketAddress transport = InetSocketAddress::ConvertFrom (address);
- m_defaultAddress = transport.GetIpv4 ();
- m_defaultPort = transport.GetPort ();
+ m_remoteAddress = transport.GetIpv4 ();
+ m_remotePort = transport.GetPort ();
uint32_t localIfIndex;
Ptr<Ipv4> ipv4 = m_node->GetObject<Ipv4> ();
- if (ipv4->GetIfIndexForDestination (m_defaultAddress, localIfIndex))
+ if (ipv4->GetIfIndexForDestination (m_remoteAddress, localIfIndex))
{
m_endPoint->SetLocalAddress (ipv4->GetAddress (localIfIndex));
}
@@ -285,30 +332,8 @@
}
int
TcpSocket::Send (const Ptr<Packet> p) //p here is just data, no headers
-{
- NS_LOG_FUNCTION;
- NS_LOG_PARAMS (this << p);
- if (m_state == ESTABLISHED || m_state == SYN_SENT || m_state == CLOSE_WAIT)
- { // Ok to buffer some data to send
- if (!m_pendingData)
- {
- m_pendingData = new PendingData (0); // Create if non-existent
- m_firstPendingSequence = m_nextTxSequence; // Note seq of first
- }
- //PendingData::Add always copies the data buffer, never modifies
- m_pendingData->Add (p->GetSize (), p->PeekData ());
- Actions_t action = ProcessEvent (APP_SEND);
- if (!ProcessAction (action))
- {
- return -1; // Failed, return zero
- }
- return p->GetSize ();
- }
- else
- {
- m_errno = ERROR_NOTCONN;
- return -1;
- }
+{ // TCP Does not deal with packets from app, just data
+ return Send(p->PeekData(), p->GetSize());
}
int TcpSocket::Send (const uint8_t* buf, uint32_t size)
@@ -324,7 +349,10 @@
}
//PendingData::Add always copies the data buffer, never modifies
m_pendingData->Add (size,buf);
+ NS_LOG_DEBUG("TcpSock::Send, pdsize " << m_pendingData->Size() <<
+ " state " << m_state);
Actions_t action = ProcessEvent (APP_SEND);
+ NS_LOG_DEBUG(" action " << action);
if (!ProcessAction (action))
{
return -1; // Failed, return zero
@@ -401,6 +429,12 @@
void
TcpSocket::ForwardUp (Ptr<Packet> packet, Ipv4Address ipv4, uint16_t port)
{
+ NS_LOG_DEBUG("Socket " << this << " got forward up" <<
+ " dport " << m_endPoint->GetLocalPort() <<
+ " daddr " << m_endPoint->GetLocalAddress() <<
+ " sport " << m_endPoint->GetPeerPort() <<
+ " saddr " << m_endPoint->GetPeerAddress());
+
NS_LOG_FUNCTION;
NS_LOG_PARAMS (this << packet << ipv4 << port);
if (m_shutdownRecv)
@@ -422,6 +456,9 @@
Events_t event = SimulationSingleton<TcpStateMachine>::Get ()->FlagsEvent (tcpHeader.GetFlags () );
Actions_t action = ProcessEvent (event); //updates the state
Address address = InetSocketAddress (ipv4, port);
+ NS_LOG_DEBUG("Socket " << this <<
+ " processing pkt action, " << action <<
+ " current state " << m_state);
ProcessPacketAction (action, packet, tcpHeader, address);
}
@@ -446,15 +483,20 @@
NS_LOG_LOGIC ("TcpSocket " << this << " moved from state " << saveState
<< " to state " <<m_state);
NS_LOG_LOGIC ("TcpSocket " << this << " pendingData " << m_pendingData);
+
+ //extra event logic is here for RX events
+ //e = SYN_ACK_RX
if (saveState == SYN_SENT && m_state == ESTABLISHED)
// this means the application side has completed its portion of
// the handshaking
{
- NotifyConnectionSucceeded ();
+ Simulator::ScheduleNow(&TcpSocket::ConnectionSucceeded, this);
+ //NotifyConnectionSucceeded ();
m_connected = true;
- m_endPoint->SetPeer (m_defaultAddress, m_defaultPort);
+ m_endPoint->SetPeer (m_remoteAddress, m_remotePort);
NS_LOG_LOGIC ("TcpSocket " << this << " Connected!");
}
+
if (needCloseNotify && !m_closeNotified)
{
NS_LOG_LOGIC ("TcpSocket " << this << " transition to CLOSED from "
@@ -483,10 +525,10 @@
header.SetSequenceNumber (m_nextTxSequence);
header.SetAckNumber (m_nextRxSequence);
header.SetSourcePort (m_endPoint->GetLocalPort ());
- header.SetDestinationPort (m_defaultPort);
+ header.SetDestinationPort (m_remotePort);
header.SetWindowSize (m_advertisedWindowSize);
m_tcp->SendPacket (p, header, m_endPoint->GetLocalAddress (),
- m_defaultAddress);
+ m_remoteAddress);
Time rto = m_rtt->RetransmitTimeout ();
if (flags & TcpHeader::SYN)
{
@@ -532,6 +574,8 @@
break;
case SYN_ACK_TX:
NS_LOG_LOGIC ("TcpSocket " << this <<" Action SYN_ACK_TX");
+ // TCP SYN Flag consumes one byte
+ ++m_nextRxSequence;
SendEmptyPacket (TcpHeader::SYN | TcpHeader::ACK);
break;
case FIN_TX:
@@ -583,29 +627,53 @@
const Address& fromAddress)
{
NS_LOG_FUNCTION;
- NS_LOG_PARAMS (this << p << "tcpHeader " << fromAddress);
+ NS_LOG_PARAMS (this << a << p << fromAddress);
uint32_t localIfIndex;
Ptr<Ipv4> ipv4 = m_node->GetObject<Ipv4> ();
switch (a)
{
case SYN_ACK_TX:
NS_LOG_LOGIC ("TcpSocket " << this <<" Action SYN_ACK_TX");
- m_defaultPort = InetSocketAddress::ConvertFrom (fromAddress).GetPort ();
- m_defaultAddress =
- InetSocketAddress::ConvertFrom (fromAddress).GetIpv4 ();
- m_endPoint->SetPeer (m_defaultAddress, m_defaultPort);
- if (ipv4->GetIfIndexForDestination (m_defaultAddress, localIfIndex))
+// m_remotePort = InetSocketAddress::ConvertFrom (fromAddress).GetPort ();
+// m_remoteAddress = InetSocketAddress::ConvertFrom (fromAddress).GetIpv4 ();
+// if (ipv4->GetIfIndexForDestination (m_remoteAddress, localIfIndex))
+// {
+// m_localAddress = ipv4->GetAddress (localIfIndex);
+// }
+ if (m_state == LISTEN) //this means we should fork a new TcpSocket
{
- m_endPoint->SetLocalAddress (ipv4->GetAddress (localIfIndex));
+ NS_LOG_DEBUG("In SYN_ACK_TX, m_state is LISTEN, this " << this);
+ //notify the server that we got a SYN
+ // If server refuses connection do nothing
+ if (!NotifyConnectionRequest(fromAddress)) return true;
+ // Clone the socket
+ Ptr<TcpSocket> newSock = Copy ();
+ NS_LOG_LOGIC ("Cloned a TcpSocket " << newSock);
+ //this listening socket should do nothing more
+ Simulator::ScheduleNow (&TcpSocket::CompleteFork, newSock,
+ p, tcpHeader,fromAddress);
+ return true;
}
- // TCP SYN consumes one byte
- m_nextRxSequence = tcpHeader.GetSequenceNumber() + SequenceNumber(1);
- SendEmptyPacket (TcpHeader::SYN | TcpHeader::ACK);
+ // This is the cloned endpoint
+ m_endPoint->SetPeer (m_remoteAddress, m_remotePort);
+ if (ipv4->GetIfIndexForDestination (m_remoteAddress, localIfIndex))
+ {
+ m_localAddress = ipv4->GetAddress (localIfIndex);
+ m_endPoint->SetLocalAddress (m_localAddress);
+ // Leave local addr in the portmap to any, as the path from
+ // remote can change and packets can arrive on different interfaces
+ //m_endPoint->SetLocalAddress (Ipv4Address::GetAny());
+ }
+ // TCP SYN consumes one byte
+ m_nextRxSequence = tcpHeader.GetSequenceNumber() + SequenceNumber(1);
+ SendEmptyPacket (TcpHeader::SYN | TcpHeader::ACK);
break;
case ACK_TX_1:
NS_LOG_LOGIC ("TcpSocket " << this <<" Action ACK_TX_1");
// TCP SYN consumes one byte
m_nextRxSequence = tcpHeader.GetSequenceNumber() + SequenceNumber(1);
+ NS_LOG_DEBUG ("TcpSocket " << this << " ACK_TX_1" <<
+ " nextRxSeq " << m_nextRxSequence);
SendEmptyPacket (TcpHeader::ACK);
m_rxWindowSize = tcpHeader.GetWindowSize ();
m_nextTxSequence = tcpHeader.GetAckNumber ();
@@ -634,7 +702,7 @@
NewAck (tcpHeader.GetAckNumber ());
break;
case NEW_SEQ_RX:
- NS_LOG_LOGIC ("TcpSocket " << this <<" Action NEW_SEQ_TX");
+ NS_LOG_LOGIC ("TcpSocket " << this <<" Action NEW_SEQ_RX");
NewRx (p, tcpHeader, fromAddress); // Process new data received
break;
case PEER_CLOSE:
@@ -664,7 +732,7 @@
{
NS_LOG_LOGIC ("TCP " << this
<< " calling AppCloseRequest");
- NotifyCloseRequested ();
+ NotifyHalfClose ();
m_closeRequestNotified = true;
}
NS_LOG_LOGIC ("TcpSocket " << this
@@ -687,7 +755,7 @@
NS_LOG_LOGIC ("TcpSocket " << this << " Connected!");
NotifyNewConnectionCreated (this, fromAddress);
m_connected = true; // ! This is bogus; fix when we clone the tcp
- m_endPoint->SetPeer (m_defaultAddress, m_defaultPort);
+ m_endPoint->SetPeer (m_remoteAddress, m_remotePort);
//treat the connection orientation final ack as a newack
CommonNewAck (tcpHeader.GetAckNumber (), true);
break;
@@ -697,6 +765,30 @@
return true;
}
+void TcpSocket::CompleteFork(Ptr<Packet> p, const TcpHeader& h, const Address& fromAddress)
+{
+ // Get port and address from peer (connecting host)
+ m_remotePort = InetSocketAddress::ConvertFrom (fromAddress).GetPort ();
+ m_remoteAddress = InetSocketAddress::ConvertFrom (fromAddress).GetIpv4 ();
+ m_endPoint = m_tcp->Allocate (m_localAddress,
+ m_localPort,
+ m_remoteAddress,
+ m_remotePort);
+ //the cloned socket with be in listen state, so manually change state
+ m_state = SYN_RCVD;
+ //equivalent to FinishBind
+ m_endPoint->SetRxCallback (MakeCallback (&TcpSocket::ForwardUp, this));
+ m_endPoint->SetDestroyCallback (MakeCallback (&TcpSocket::Destroy, this));
+ ProcessPacketAction(SYN_ACK_TX, p, h, fromAddress);
+ }
+
+void TcpSocket::ConnectionSucceeded()
+{ // We would preferred to have scheduled an event directly to
+ // NotifyConnectionSucceeded, but (sigh) these are protected
+ // and we can get the address of it :(
+ NotifyConnectionSucceeded();
+}
+
bool TcpSocket::SendPendingData (bool withAck)
{
NS_LOG_FUNCTION;
@@ -751,7 +843,7 @@
header.SetSequenceNumber (m_nextTxSequence);
header.SetAckNumber (m_nextRxSequence);
header.SetSourcePort (m_endPoint->GetLocalPort());
- header.SetDestinationPort (m_defaultPort);
+ header.SetDestinationPort (m_remotePort);
if (m_shutdownSend)
{
m_errno = ERROR_SHUTDOWN;
@@ -769,7 +861,7 @@
NS_LOG_LOGIC ("About to send a packet with flags: " << flags);
m_tcp->SendPacket (p, header,
m_endPoint->GetLocalAddress (),
- m_defaultAddress);
+ m_remoteAddress);
m_rtt->SentSeq(m_nextTxSequence, sz); // notify the RTT
// Notify the application
Simulator::ScheduleNow(&TcpSocket::NotifyDataSent, this, p->GetSize ());
@@ -820,7 +912,15 @@
{
NS_LOG_FUNCTION;
NS_LOG_PARAMS (this << p << "tcpHeader " << fromAddress);
- NS_LOG_LOGIC ("TcpSocket " << this << " NewRx, p.size is " << p->GetSize () );
+ NS_LOG_LOGIC ("TcpSocket " << this << " NewRx,"
+ << " seq " << tcpHeader.GetSequenceNumber()
+ << " ack " << tcpHeader.GetAckNumber()
+ << " p.size is " << p->GetSize () );
+ NS_LOG_DEBUG ("TcpSocket " << this <<
+ " NewRx," <<
+ " seq " << tcpHeader.GetSequenceNumber() <<
+ " ack " << tcpHeader.GetAckNumber() <<
+ " p.size is " << p->GetSize());
States_t origState = m_state;
uint32_t s = p->GetSize (); // Size of associated data
if (s == 0)
@@ -842,7 +942,7 @@
m_nextRxSequence += s; // Advance next expected sequence
//bytesReceived += s; // Statistics
NS_LOG_LOGIC("Case 1, advanced nrxs to " << m_nextRxSequence );
- NotifyDataReceived (p, fromAddress);
+ NotifyDataReceived (p, fromAddress);
if (m_closeNotified)
{
NS_LOG_LOGIC ("Tcp " << this << " HuH? Got data after closeNotif");
@@ -970,6 +1070,11 @@
SendPendingData();
}
+Ptr<TcpSocket> TcpSocket::Copy ()
+{
+ return CopyObject<TcpSocket> (this);
+}
+
void TcpSocket::NewAck (SequenceNumber seq)
{ // New acknowledgement up to sequence number "seq"
// Adjust congestion window in response to new ack's received
@@ -1103,12 +1208,12 @@
tcpHeader.SetSequenceNumber (m_nextTxSequence);
tcpHeader.SetAckNumber (m_nextRxSequence);
tcpHeader.SetSourcePort (m_endPoint->GetLocalPort());
- tcpHeader.SetDestinationPort (m_defaultPort);
+ tcpHeader.SetDestinationPort (m_remotePort);
tcpHeader.SetFlags (flags);
tcpHeader.SetWindowSize (m_advertisedWindowSize);
m_tcp->SendPacket (p, tcpHeader, m_endPoint->GetLocalAddress (),
- m_defaultAddress);
+ m_remoteAddress);
}
}//namespace ns3
--- a/src/internet-node/tcp-socket.h Fri Mar 14 16:36:55 2008 -0700
+++ b/src/internet-node/tcp-socket.h Fri Mar 14 16:37:02 2008 -0700
@@ -46,6 +46,7 @@
* Create an unbound tcp socket.
*/
TcpSocket ();
+ TcpSocket (const TcpSocket& sock);
virtual ~TcpSocket ();
void SetNode (Ptr<Node> node);
@@ -83,7 +84,9 @@
const Address& fromAddress);
Actions_t ProcessEvent (Events_t e);
bool SendPendingData(bool withAck = false);
-
+ void CompleteFork(Ptr<Packet>, const TcpHeader&, const Address& fromAddress);
+ void ConnectionSucceeded();
+
//methods for window management
virtual uint32_t UnAckDataCount(); // Return count of number of unacked bytes
virtual uint32_t BytesInFlight(); // Return total bytes in flight
@@ -93,6 +96,7 @@
// Manage data tx/rx
void NewRx (Ptr<Packet>, const TcpHeader&, const Address&);
// XXX This should be virtual and overridden
+ Ptr<TcpSocket> Copy ();
void NewAck (SequenceNumber seq);
// XXX This should be virtual and overridden
void DupAck (const TcpHeader& t, uint32_t count);
@@ -109,8 +113,12 @@
Ipv4EndPoint *m_endPoint;
Ptr<Node> m_node;
Ptr<TcpL4Protocol> m_tcp;
- Ipv4Address m_defaultAddress;
- uint16_t m_defaultPort;
+ Ipv4Address m_remoteAddress;
+ uint16_t m_remotePort;
+ //these two are so that the socket/endpoint cloning works
+ Ipv4Address m_localAddress;
+ uint16_t m_localPort;
+ //XXX Dead code?
Callback<void, Ptr<Socket>, uint32_t, const Address &> m_dummyRxCallback;
Callback<void, Ptr<Socket>, uint8_t const*, uint32_t, const Address &>
m_rxCallback;
--- a/src/internet-node/udp-l4-protocol.cc Fri Mar 14 16:36:55 2008 -0700
+++ b/src/internet-node/udp-l4-protocol.cc Fri Mar 14 16:37:02 2008 -0700
@@ -110,11 +110,11 @@
}
Ipv4EndPoint *
-UdpL4Protocol::Allocate (Ipv4Address address, Ipv4Address localInterface)
+UdpL4Protocol::Allocate (Ipv4Address address)
{
NS_LOG_FUNCTION;
NS_LOG_PARAMS (this << address);
- return m_endPoints->Allocate (address, localInterface);
+ return m_endPoints->Allocate (address);
}
Ipv4EndPoint *
@@ -126,21 +126,20 @@
}
Ipv4EndPoint *
-UdpL4Protocol::Allocate (Ipv4Address address, uint16_t port, Ipv4Address localInterface)
+UdpL4Protocol::Allocate (Ipv4Address address, uint16_t port)
{
NS_LOG_FUNCTION;
NS_LOG_PARAMS (this << address << port);
- return m_endPoints->Allocate (address, port, localInterface);
+ return m_endPoints->Allocate (address, port);
}
Ipv4EndPoint *
UdpL4Protocol::Allocate (Ipv4Address localAddress, uint16_t localPort,
- Ipv4Address peerAddress, uint16_t peerPort,
- Ipv4Address localInterface)
+ Ipv4Address peerAddress, uint16_t peerPort)
{
NS_LOG_FUNCTION;
NS_LOG_PARAMS (this << localAddress << localPort << peerAddress << peerPort);
return m_endPoints->Allocate (localAddress, localPort,
- peerAddress, peerPort, localInterface);
+ peerAddress, peerPort);
}
void
--- a/src/internet-node/udp-l4-protocol.h Fri Mar 14 16:36:55 2008 -0700
+++ b/src/internet-node/udp-l4-protocol.h Fri Mar 14 16:37:02 2008 -0700
@@ -58,13 +58,11 @@
Ptr<Socket> CreateSocket (void);
Ipv4EndPoint *Allocate (void);
- Ipv4EndPoint *Allocate (Ipv4Address address, Ipv4Address localInterface);
+ Ipv4EndPoint *Allocate (Ipv4Address address);
Ipv4EndPoint *Allocate (uint16_t port);
- Ipv4EndPoint *Allocate (Ipv4Address address, uint16_t port,
- Ipv4Address localInterface);
+ Ipv4EndPoint *Allocate (Ipv4Address address, uint16_t port);
Ipv4EndPoint *Allocate (Ipv4Address localAddress, uint16_t localPort,
- Ipv4Address peerAddress, uint16_t peerPort,
- Ipv4Address localInterface);
+ Ipv4Address peerAddress, uint16_t peerPort);
void DeAllocate (Ipv4EndPoint *endPoint);
--- a/src/internet-node/udp-socket.cc Fri Mar 14 16:36:55 2008 -0700
+++ b/src/internet-node/udp-socket.cc Fri Mar 14 16:37:02 2008 -0700
@@ -139,16 +139,6 @@
InetSocketAddress transport = InetSocketAddress::ConvertFrom (address);
Ipv4Address ipv4 = transport.GetIpv4 ();
uint16_t port = transport.GetPort ();
-
- Ipv4Address localInterface = Ipv4Address::GetAny ();
- if (ipv4 != Ipv4Address::GetAny ())
- {
- Ptr<Ipv4> ipv4_api = m_node->GetObject<Ipv4> ();
- // Assert that the given address matches an existing local interface
- NS_ASSERT (ipv4_api->FindInterfaceForAddr (ipv4) != 0);
- localInterface = ipv4;
- }
-
if (ipv4 == Ipv4Address::GetAny () && port == 0)
{
m_endPoint = m_udp->Allocate ();
@@ -159,11 +149,11 @@
}
else if (ipv4 != Ipv4Address::GetAny () && port == 0)
{
- m_endPoint = m_udp->Allocate (ipv4, localInterface);
+ m_endPoint = m_udp->Allocate (ipv4);
}
else if (ipv4 != Ipv4Address::GetAny () && port != 0)
{
- m_endPoint = m_udp->Allocate (ipv4, port, localInterface);
+ m_endPoint = m_udp->Allocate (ipv4, port);
}
return FinishBind ();
--- a/src/node/socket.cc Fri Mar 14 16:36:55 2008 -0700
+++ b/src/node/socket.cc Fri Mar 14 16:37:02 2008 -0700
@@ -164,8 +164,11 @@
}
else
{
- // refuse all incomming connections by default.
- return false;
+ // accept all incoming connections by default.
+ // this way people writing code don't have to do anything
+ // special like register a callback that returns true
+ // just to get incoming connections
+ return true;
}
}