Query in tracing TCP socket

233 views
Skip to first unread message

Konstantinos

unread,
Jan 8, 2014, 5:33:51 PM1/8/14
to ns-3-...@googlegroups.com
Hi all,

I have modified the bulk-send-application to use more than one tcp sockets for sending a packet, something like a multi-path tcp application but it creates multiple instances of TCP connections over different paths.

an example with 3 paths is seen bellow

           + ----- GW0 ---- +
src (o)  + ----- GW1 ---- + (o) dst
           + ----- GW2 -----+ 

I have created the sockets and the simulation runs fine.

But when I try to trace the congestion window I do not get it for all the sockets. For one socket, I can trace it fine. For two, I only trace the first. For three I trace the first and the third. In general, I can trace only the even number of socket. 

I guess that there is something wrong with the path I am using but I want to confirm why it is that way.

This is what I am using where "sockets" are the number of different sockets I have created and tr_node (src) is the node I want to trace:

for (int s=0; s<sockets; s++)
{
std::stringstream tmp_file;
tmp_file << cwnd_tr_file_name.c_str() <<"-" << s << ".txt" ;
Ptr<OutputStreamWrapper> stream = ascii.CreateFileStream(tmp_file.str());
std::stringstream tr_path;
tr_path << "/NodeList/" << tr_node << "/$ns3::TcpL4Protocol/SocketList/"<< s <<"/CongestionWindow";
NS_LOG_UNCOND(tr_path.str());
Config::ConnectWithoutContext (tr_path.str(),MakeBoundCallback (&CwndTracer, stream));
}

My question is why the "even" number of socket in SocketList fire for this node? 
Even if TcpL4Protocol/SocketList/ has reference for ALL the sockets in the simulation, I have made sure that the sockets for each node/application are created one after the other in a single loop, so they should be sequential, right?

If I use this path it works for all sockets.
tr_path << "/NodeList/" << tr_node << "/$ns3::TcpL4Protocol/SocketList/"<< 2*s <<"/CongestionWindow";

Regards,
Konstantinos

Tommaso Pecorella

unread,
Jan 8, 2014, 11:08:05 PM1/8/14
to ns-3-...@googlegroups.com
Evil bug (or it's a feature ?)

std::vector<Ptr<TcpSocketBase> > m_sockets;      //!< list of sockets

class TcpSocketBase : public TcpSocket

class TcpSocket : public Socket


Can you check the "true" type of the Sockets obtained by the given patch ?
I'm not going to bet on it, but I'm guessing: one is a TcpSocketBase and the other is a TcpSocket…

If this is it, then it's a bug. An evil one. And it belongs to Path configs.

Cheers,

T.

Tommaso Pecorella

unread,
Jan 9, 2014, 10:26:18 AM1/9/14
to ns-3-...@googlegroups.com
Hi Kostas,

I shouldn't try to guess when I'm tired. Chances are that I'll completely miss the target.

This behavior is normal.

void

TcpSocketBase::CompleteFork (Ptr<Packet> p, const TcpHeader& h,

                             const Address& fromAddress, const Address& toAddress)


A TCP socket starts in LISTENING state (in the server). Once they're connected, the socket is forked, and a copy of itself is put in the socket list.
Hence, one socket is (still) listening, the other is connected.

In order to be sure of what is what, you should track their state.

This behavior (double sockets) should be only in the server, as the client (i.e., who's starting the connection) shouldn't fork anything.
Note: I have (still) no clue about why the ender have doubled sockets as well...

By the way… since sockets are just pushed into a list (and they can be popped as well), you can't be sure that the sequence is respected. Personally, I wouldn't trust it.

If you feel this is a bad behavior (indeed, it's annoying), fill a bug. I have no clue of a possible solution, tho.

Cheers,

T.


On Wednesday, January 8, 2014 5:33:51 PM UTC+1, Konstantinos wrote:

Konstantinos

unread,
Jan 9, 2014, 2:06:53 PM1/9/14
to ns-3-...@googlegroups.com
Hi Tomasso,

Thanks for the explanation. 
The thing is, that the source node (the one with the BulkSendApp) shows this behaviour. Which means that this 'fork' seems to happen also at the client, not only the server.

Tommaso Pecorella

unread,
Jan 9, 2014, 7:46:56 PM1/9/14
to ns-3-...@googlegroups.com
Hi Kostas,

that's why I'm still not convinced. I have an extremely simple test program (just open sockets, connect, send a packet. Nothing more). And the client does NOT fork.
Hence, I'm still not totally convinced.

Cheers,

T.

Konstantinos

unread,
Jan 9, 2014, 10:20:44 PM1/9/14
to ns-3-...@googlegroups.com
Hi Thomasso,

There is something else that I spotted today about the path.

The trace source for CongestionWindow is defined in each TCP variant implementation and not in the TcpSocketBase, even though all of them have it.

The path suggested by the API to connect is /NodeList/[i]/$ns3::TcpL4Protocol/SocketList/[i]/$ns3::<TcpVariant>/CongestionWindow
but the example suggests (and it works) to leave the last part $ns3::<TcpVariant> which for me either the API is wrong/misleading or the tracing system or it is just me.

How can this be explained? 

Tommaso Pecorella

unread,
Jan 9, 2014, 10:24:49 PM1/9/14
to ns-3-...@googlegroups.com
Ok, I got this (I think).

It's definitely a bug, so please fill a bug (you're the one who did find it). If you don't do it, I'll do it for you. You're warned.

When a socket is created it is added to the m_sockets list:

Ptr<Socket>

TcpL4Protocol::CreateSocket (TypeId socketTypeId)

{

  NS_LOG_FUNCTION_NOARGS ();

  ObjectFactory rttFactory;

  ObjectFactory socketFactory;

  rttFactory.SetTypeId (m_rttTypeId);

  socketFactory.SetTypeId (socketTypeId);

  Ptr<RttEstimator> rtt = rttFactory.Create<RttEstimator> ();

  Ptr<TcpSocketBase> socket = socketFactory.Create<TcpSocketBase> ();

  socket->SetNode (m_node);

  socket->SetTcp (this);

  socket->SetRtt (rtt);

  m_sockets.push_back (socket);

  return socket;

}


When you do "Bind", the socket is added *again* to the list:

int

TcpSocketBase::Bind (void)

{

  NS_LOG_FUNCTION (this);

  m_endPoint = m_tcp->Allocate ();

  if (0 == m_endPoint)

    {

      m_errno = ERROR_ADDRNOTAVAIL;

      return -1;

    }

  m_tcp->m_sockets.push_back (this);

  return SetupCallback ();

}


That's the sender.

The receiver have the same "thing" replicated, but it's in:

void

TcpSocketBase::CompleteFork (Ptr<Packet> p, const TcpHeader& h,

                             const Address& fromAddress, const Address& toAddress)


Now, the point is: this is stupid. Moreover, these are plainly duplicate entries (or not ?).
Not quite. Sockets are used through Smart Pointers. As a consequence, when you modify it, it might be copied.
In this case they seems to be exactly the same.

Solution 1: do not add the socket to the socket list as soon as it's created.
Solution 2: do a check before adding a socket to the list (if it's already in the list, don't add it again).


Summarizing. The true™ answer to your question is: it's not that the callback wasn't fired for odd sockets, it's that you was setting up a callback on the very same socket (even and odd sockets are the same socket for real).


Cheers,

T.


Tommaso Pecorella

unread,
Jan 9, 2014, 10:36:28 PM1/9/14
to ns-3-...@googlegroups.com
Btw, the bugs are actually TWO.

Bug 1: sockets are duplicate in the sender (i.e., who's using Connect).
Bug 2: socket is duplicate **and not copied** in the receiver (who's using Listen).

In the receiver, the socket should be, indeed, duplicated. however it isn't !

I'm not 100% sure, but I'm ready to bet. If you open one socket and you try to connect to it from two different peers, it will go fishin'.
It might be not 100% evident at first, but the "two" sockets will be dependent on each other. If you close one, the other will close as well.
Sadly, I have no time to test this, but I'm half sure it would happen.

Scenario (if you wanna try).

A---B---C

B opens a socket in listening.
A connects to it.
Is C able to do the same ? (it should)
If C is fine, try closing the socket from A to B. What happens to the socket from B to C ?

Cheers,

T.

Konstantinos

unread,
Jan 9, 2014, 11:07:36 PM1/9/14
to ns-3-...@googlegroups.com
Will try the scenario tomorrow because now it is not the time for clear thinking. 


Regards,
K.
Reply all
Reply to author
Forward
0 new messages