merge bug 213 repo

This commit is contained in:
Mathieu Lacage
2008-06-13 17:20:55 -07:00
15 changed files with 414 additions and 203 deletions

View File

@@ -204,7 +204,7 @@ void WriteUntilBufferFull (Ptr<Socket> localSocket, uint32_t nBytes)
char m = toascii (97 + i % 26);
data[i] = m;
}
uint32_t amountSent = localSocket->Send (data, curSize);
uint32_t amountSent = localSocket->Send (data, curSize, 0);
if(amountSent < curSize)
{
std::cout << "Socket blocking, returning" << std::endl;

View File

@@ -103,14 +103,9 @@ void PacketSink::StopApplication() // Called at time specified by Stop
void PacketSink::HandleRead (Ptr<Socket> socket)
{
Ptr<Packet> packet;
while (packet = socket->Recv ())
Address from;
while (packet = socket->RecvFrom (from))
{
SocketRxAddressTag tag;
bool found;
found = packet->FindFirstMatchingTag (tag);
NS_ASSERT (found);
Address from = tag.GetAddress ();
// XXX packet->RemoveTag (tag);
if (InetSocketAddress::IsMatchingType (from))
{
InetSocketAddress address = InetSocketAddress::ConvertFrom (from);

View File

@@ -154,14 +154,9 @@ UdpEchoClient::HandleRead (Ptr<Socket> socket)
{
NS_LOG_FUNCTION (this << socket);
Ptr<Packet> packet;
while (packet = socket->Recv ())
Address from;
while (packet = socket->RecvFrom (from))
{
SocketRxAddressTag tag;
bool found;
found = packet->FindFirstMatchingTag (tag);
NS_ASSERT (found);
Address from = tag.GetAddress ();
// XXX packet->RemoveTag (tag);
if (InetSocketAddress::IsMatchingType (from))
{
InetSocketAddress address = InetSocketAddress::ConvertFrom (from);

View File

@@ -95,14 +95,9 @@ void
UdpEchoServer::HandleRead (Ptr<Socket> socket)
{
Ptr<Packet> packet;
while (packet = socket->Recv ())
Address from;
while (packet = socket->RecvFrom (from))
{
SocketRxAddressTag tag;
bool found;
found = packet->FindFirstMatchingTag (tag);
NS_ASSERT (found);
Address from = tag.GetAddress ();
// XXX packet->RemoveTag (tag);
if (InetSocketAddress::IsMatchingType (from))
{
InetSocketAddress address = InetSocketAddress::ConvertFrom (from);
@@ -110,7 +105,7 @@ UdpEchoServer::HandleRead (Ptr<Socket> socket)
address.GetIpv4());
NS_LOG_LOGIC ("Echoing packet");
socket->SendTo (packet, from);
socket->SendTo (packet, 0, from);
}
}
}

View File

@@ -346,8 +346,10 @@ TcpSocketImpl::Connect (const Address & address)
}
return -1;
}
//p here is just data, no headers
int
TcpSocketImpl::Send (const Ptr<Packet> p) //p here is just data, no headers
TcpSocketImpl::Send (Ptr<Packet> p, uint32_t flags)
{
NS_LOG_FUNCTION (this << p);
if (m_state == ESTABLISHED || m_state == SYN_SENT || m_state == CLOSE_WAIT)
@@ -382,11 +384,6 @@ TcpSocketImpl::Send (const Ptr<Packet> p) //p here is just data, no headers
}
}
int TcpSocketImpl::Send (const uint8_t* buf, uint32_t size)
{
return Send (Create<Packet> (buf, size));
}
int TcpSocketImpl::DoSendTo (Ptr<Packet> p, const Address &address)
{
NS_LOG_FUNCTION (this << p << address);
@@ -420,7 +417,7 @@ int TcpSocketImpl::DoSendTo (Ptr<Packet> p, Ipv4Address ipv4, uint16_t port)
}
int
TcpSocketImpl::SendTo (Ptr<Packet> p, const Address &address)
TcpSocketImpl::SendTo (Ptr<Packet> p, uint32_t flags, const Address &address)
{
NS_LOG_FUNCTION (this << address << p);
if (!m_connected)
@@ -430,7 +427,7 @@ TcpSocketImpl::SendTo (Ptr<Packet> p, const Address &address)
}
else
{
return Send (p); //drop the address according to BSD manpages
return Send (p, flags); //drop the address according to BSD manpages
}
}
@@ -532,6 +529,23 @@ TcpSocketImpl::GetRxAvailable (void) const
return m_rxAvailable;
}
Ptr<Packet>
TcpSocketImpl::RecvFrom (uint32_t maxSize, uint32_t flags,
Address &fromAddress)
{
NS_LOG_FUNCTION (this << maxSize << flags);
Ptr<Packet> packet = Recv (maxSize, flags);
if (packet != 0)
{
SocketAddressTag tag;
bool found;
found = packet->FindFirstMatchingTag (tag);
NS_ASSERT (found);
fromAddress = tag.GetAddress ();
}
return packet;
}
void
TcpSocketImpl::ForwardUp (Ptr<Packet> packet, Ipv4Address ipv4, uint16_t port)
{
@@ -1048,7 +1062,7 @@ void TcpSocketImpl::NewRx (Ptr<Packet> p,
m_nextRxSequence += s; // Advance next expected sequence
//bytesReceived += s; // Statistics
NS_LOG_LOGIC("Case 1, advanced nrxs to " << m_nextRxSequence );
SocketRxAddressTag tag;
SocketAddressTag tag;
tag.SetAddress (fromAddress);
p->AddTag (tag);
//buffer this, it'll be read by call to Recv
@@ -1106,7 +1120,7 @@ void TcpSocketImpl::NewRx (Ptr<Packet> p,
i->second = 0; // relase reference to already buffered
}
// Save for later delivery
SocketRxAddressTag tag;
SocketAddressTag tag;
tag.SetAddress (fromAddress);
p->AddTag (tag);
m_bufferedData[tcpHeader.GetSequenceNumber () ] = p;

View File

@@ -79,14 +79,14 @@ public:
virtual int ShutdownSend (void);
virtual int ShutdownRecv (void);
virtual int Connect(const Address &address);
virtual int Send (Ptr<Packet> p);
virtual int Send (const uint8_t* buf, uint32_t size);
virtual int SendTo(Ptr<Packet> p, const Address &address);
virtual uint32_t GetTxAvailable (void) const;
virtual int Listen(uint32_t queueLimit);
virtual Ptr<Packet> Recv (uint32_t maxSize, uint32_t flags);
virtual uint32_t GetTxAvailable (void) const;
virtual int Send (Ptr<Packet> p, uint32_t flags);
virtual int SendTo(Ptr<Packet> p, uint32_t flags, const Address &toAddress);
virtual uint32_t GetRxAvailable (void) const;
virtual Ptr<Packet> Recv (uint32_t maxSize, uint32_t flags);
virtual Ptr<Packet> RecvFrom (uint32_t maxSize, uint32_t flags,
Address &fromAddress);
private:
friend class Tcp;

View File

@@ -224,9 +224,9 @@ UdpSocketImpl::Listen (uint32_t queueLimit)
}
int
UdpSocketImpl::Send (Ptr<Packet> p)
UdpSocketImpl::Send (Ptr<Packet> p, uint32_t flags)
{
NS_LOG_FUNCTION (this << p);
NS_LOG_FUNCTION (this << p << flags);
if (!m_connected)
{
@@ -239,7 +239,7 @@ UdpSocketImpl::Send (Ptr<Packet> p)
int
UdpSocketImpl::DoSend (Ptr<Packet> p)
{
NS_LOG_FUNCTION_NOARGS ();
NS_LOG_FUNCTION (this << p);
if (m_endPoint == 0)
{
if (Bind () == -1)
@@ -380,19 +380,28 @@ UdpSocketImpl::GetTxAvailable (void) const
}
int
UdpSocketImpl::SendTo (Ptr<Packet> p, const Address &address)
UdpSocketImpl::SendTo (Ptr<Packet> p, uint32_t flags, const Address &address)
{
NS_LOG_FUNCTION (this << address << p);
NS_LOG_FUNCTION (this << p << flags << address);
InetSocketAddress transport = InetSocketAddress::ConvertFrom (address);
Ipv4Address ipv4 = transport.GetIpv4 ();
uint16_t port = transport.GetPort ();
return DoSendTo (p, ipv4, port);
}
uint32_t
UdpSocketImpl::GetRxAvailable (void) const
{
NS_LOG_FUNCTION_NOARGS ();
// We separately maintain this state to avoid walking the queue
// every time this might be called
return m_rxAvailable;
}
Ptr<Packet>
UdpSocketImpl::Recv (uint32_t maxSize, uint32_t flags)
{
NS_LOG_FUNCTION_NOARGS ();
NS_LOG_FUNCTION (this << maxSize << flags);
if (m_deliveryQueue.empty() )
{
return 0;
@@ -410,13 +419,21 @@ UdpSocketImpl::Recv (uint32_t maxSize, uint32_t flags)
return p;
}
uint32_t
UdpSocketImpl::GetRxAvailable (void) const
Ptr<Packet>
UdpSocketImpl::RecvFrom (uint32_t maxSize, uint32_t flags,
Address &fromAddress)
{
NS_LOG_FUNCTION_NOARGS ();
// We separately maintain this state to avoid walking the queue
// every time this might be called
return m_rxAvailable;
NS_LOG_FUNCTION (this << maxSize << flags);
Ptr<Packet> packet = Recv (maxSize, flags);
if (packet != 0)
{
SocketAddressTag tag;
bool found;
found = packet->FindFirstMatchingTag (tag);
NS_ASSERT (found);
fromAddress = tag.GetAddress ();
}
return packet;
}
void
@@ -431,7 +448,7 @@ UdpSocketImpl::ForwardUp (Ptr<Packet> packet, Ipv4Address ipv4, uint16_t port)
if ((m_rxAvailable + packet->GetSize ()) <= m_rcvBufSize)
{
Address address = InetSocketAddress (ipv4, port);
SocketRxAddressTag tag;
SocketAddressTag tag;
tag.SetAddress (address);
packet->AddTag (tag);
m_deliveryQueue.push (packet);
@@ -638,7 +655,7 @@ UdpSocketImplTest::RunTests (void)
// Unicast test
m_receivedPacket = Create<Packet> ();
m_receivedPacket2 = Create<Packet> ();
NS_TEST_ASSERT_EQUAL (txSocket->SendTo ( Create<Packet> (123),
NS_TEST_ASSERT_EQUAL (txSocket->SendTo ( Create<Packet> (123), 0,
InetSocketAddress (Ipv4Address("10.0.0.1"), 1234)), 123);
Simulator::Run ();
NS_TEST_ASSERT_EQUAL (m_receivedPacket->GetSize (), 123);
@@ -651,7 +668,7 @@ UdpSocketImplTest::RunTests (void)
m_receivedPacket = Create<Packet> ();
m_receivedPacket2 = Create<Packet> ();
NS_TEST_ASSERT_EQUAL (txSocket->SendTo ( Create<Packet> (123),
NS_TEST_ASSERT_EQUAL (txSocket->SendTo ( Create<Packet> (123), 0,
InetSocketAddress (Ipv4Address("255.255.255.255"), 1234)), 123);
Simulator::Run ();
NS_TEST_ASSERT_EQUAL (m_receivedPacket->GetSize (), 123);
@@ -673,7 +690,7 @@ UdpSocketImplTest::RunTests (void)
m_receivedPacket = Create<Packet> ();
m_receivedPacket2 = Create<Packet> ();
NS_TEST_ASSERT_EQUAL (txSocket->SendTo (Create<Packet> (123),
NS_TEST_ASSERT_EQUAL (txSocket->SendTo (Create<Packet> (123), 0,
InetSocketAddress (Ipv4Address("255.255.255.255"), 1234)), 123);
Simulator::Run ();
NS_TEST_ASSERT_EQUAL (m_receivedPacket->GetSize (), 123);

View File

@@ -65,12 +65,13 @@ public:
virtual int ShutdownRecv (void);
virtual int Connect(const Address &address);
virtual int Listen (uint32_t queueLimit);
virtual int Send (Ptr<Packet> p);
virtual int SendTo (Ptr<Packet> p, const Address &address);
virtual uint32_t GetTxAvailable (void) const;
virtual Ptr<Packet> Recv (uint32_t maxSize, uint32_t flags);
virtual int Send (Ptr<Packet> p, uint32_t flags);
virtual int SendTo (Ptr<Packet> p, uint32_t flags, const Address &address);
virtual uint32_t GetRxAvailable (void) const;
virtual Ptr<Packet> Recv (uint32_t maxSize, uint32_t flags);
virtual Ptr<Packet> RecvFrom (uint32_t maxSize, uint32_t flags,
Address &fromAddress);
private:
// Attributes set through UdpSocket base class

View File

@@ -230,7 +230,7 @@ PacketSocket::Listen(uint32_t queueLimit)
}
int
PacketSocket::Send (Ptr<Packet> p)
PacketSocket::Send (Ptr<Packet> p, uint32_t flags)
{
NS_LOG_FUNCTION_NOARGS ();
if (m_state == STATE_OPEN ||
@@ -239,7 +239,7 @@ PacketSocket::Send (Ptr<Packet> p)
m_errno = ERROR_NOTCONN;
return -1;
}
return SendTo (p, m_destAddr);
return SendTo (p, flags, m_destAddr);
}
uint32_t
@@ -275,7 +275,7 @@ PacketSocket::GetTxAvailable (void) const
}
int
PacketSocket::SendTo(Ptr<Packet> p, const Address &address)
PacketSocket::SendTo (Ptr<Packet> p, uint32_t flags, const Address &address)
{
NS_LOG_FUNCTION_NOARGS ();
PacketSocketAddress ad;
@@ -361,7 +361,7 @@ PacketSocket::ForwardUp (Ptr<NetDevice> device, Ptr<Packet> packet,
if ((m_rxAvailable + packet->GetSize ()) <= m_rcvBufSize)
{
SocketRxAddressTag tag;
SocketAddressTag tag;
tag.SetAddress (address);
packet->AddTag (tag);
m_deliveryQueue.push (packet);
@@ -381,6 +381,15 @@ PacketSocket::ForwardUp (Ptr<NetDevice> device, Ptr<Packet> packet,
}
}
uint32_t
PacketSocket::GetRxAvailable (void) const
{
NS_LOG_FUNCTION_NOARGS ();
// We separately maintain this state to avoid walking the queue
// every time this might be called
return m_rxAvailable;
}
Ptr<Packet>
PacketSocket::Recv (uint32_t maxSize, uint32_t flags)
{
@@ -402,13 +411,20 @@ PacketSocket::Recv (uint32_t maxSize, uint32_t flags)
return p;
}
uint32_t
PacketSocket::GetRxAvailable (void) const
Ptr<Packet>
PacketSocket::RecvFrom (uint32_t maxSize, uint32_t flags, Address &fromAddress)
{
NS_LOG_FUNCTION_NOARGS ();
// We separately maintain this state to avoid walking the queue
// every time this might be called
return m_rxAvailable;
Ptr<Packet> packet = Recv (maxSize, flags);
if (packet != 0)
{
SocketAddressTag tag;
bool found;
found = packet->FindFirstMatchingTag (tag);
NS_ASSERT (found);
fromAddress = tag.GetAddress ();
}
return packet;
}
}//namespace ns3

View File

@@ -93,13 +93,13 @@ public:
virtual int ShutdownRecv (void);
virtual int Connect(const Address &address);
virtual int Listen(uint32_t queueLimit);
virtual int Send (Ptr<Packet> p);
virtual uint32_t GetTxAvailable (void) const;
virtual int SendTo(Ptr<Packet> p, const Address &address);
virtual Ptr<Packet> Recv (uint32_t maxSize, uint32_t flags);
virtual int Send (Ptr<Packet> p, uint32_t flags);
virtual int SendTo(Ptr<Packet> p, uint32_t flags, const Address &toAddress);
virtual uint32_t GetRxAvailable (void) const;
virtual Ptr<Packet> Recv (uint32_t maxSize, uint32_t flags);
virtual Ptr<Packet> RecvFrom (uint32_t maxSize, uint32_t flags,
Address &fromAddress);
private:
void ForwardUp (Ptr<NetDevice> device, Ptr<Packet> packet,

View File

@@ -40,13 +40,6 @@ Socket::~Socket ()
NS_LOG_FUNCTION_NOARGS ();
}
void
Socket::SetCloseUnblocksCallback (Callback<void,Ptr<Socket> > closeUnblocks)
{
NS_LOG_FUNCTION_NOARGS ();
m_closeUnblocks = closeUnblocks;
}
Ptr<Socket>
Socket::CreateSocket (Ptr<Node> node, TypeId tid)
{
@@ -110,6 +103,13 @@ Socket::SetRecvCallback (Callback<void, Ptr<Socket> > receivedData)
m_receivedData = receivedData;
}
int
Socket::Send (Ptr<Packet> p)
{
NS_LOG_FUNCTION_NOARGS ();
return Send (p, 0);
}
void
Socket::NotifyCloseUnblocks (void)
{
@@ -125,7 +125,8 @@ int Socket::Listen (uint32_t queueLimit)
return 0; //XXX the base class version does nothing
}
int Socket::Send (const uint8_t* buf, uint32_t size)
int
Socket::Send (const uint8_t* buf, uint32_t size, uint32_t flags)
{
NS_LOG_FUNCTION_NOARGS ();
Ptr<Packet> p;
@@ -137,24 +138,12 @@ int Socket::Send (const uint8_t* buf, uint32_t size)
{
p = Create<Packet> (size);
}
return Send (p);
}
Ptr<Packet>
Socket::Recv (void)
{
return Recv (std::numeric_limits<uint32_t>::max(), 0);
return Send (p, flags);
}
int
Socket::Recv (uint8_t* buf, uint32_t size, uint32_t flags)
{
Ptr<Packet> p = Recv (size, flags); // read up to "size" bytes
memcpy (buf, p->PeekData (), p->GetSize());
return p->GetSize ();
}
int Socket::SendTo (const uint8_t* buf, uint32_t size, const Address &address)
Socket::SendTo (const uint8_t* buf, uint32_t size, uint32_t flags,
const Address &toAddress)
{
NS_LOG_FUNCTION_NOARGS ();
Ptr<Packet> p;
@@ -166,7 +155,48 @@ int Socket::SendTo (const uint8_t* buf, uint32_t size, const Address &address)
{
p = Create<Packet> (size);
}
return SendTo (p, address);
return SendTo (p, flags, toAddress);
}
Ptr<Packet>
Socket::Recv (void)
{
NS_LOG_FUNCTION_NOARGS ();
return Recv (std::numeric_limits<uint32_t>::max(), 0);
}
int
Socket::Recv (uint8_t* buf, uint32_t size, uint32_t flags)
{
NS_LOG_FUNCTION_NOARGS ();
Ptr<Packet> p = Recv (size, flags); // read up to "size" bytes
if (p == 0)
{
return 0;
}
memcpy (buf, p->PeekData (), p->GetSize());
return p->GetSize ();
}
Ptr<Packet>
Socket::RecvFrom (Address &fromAddress)
{
NS_LOG_FUNCTION_NOARGS ();
return RecvFrom (std::numeric_limits<uint32_t>::max(), 0, fromAddress);
}
int
Socket::RecvFrom (uint8_t* buf, uint32_t size, uint32_t flags,
Address &fromAddress)
{
NS_LOG_FUNCTION_NOARGS ();
Ptr<Packet> p = RecvFrom (size, flags, fromAddress);
if (p == 0)
{
return 0;
}
memcpy (buf, p->PeekData (), p->GetSize());
return p->GetSize ();
}
void
@@ -281,54 +311,54 @@ Socket::NotifyDataRecv (void)
* Socket Tags
***************************************************************/
SocketRxAddressTag::SocketRxAddressTag ()
SocketAddressTag::SocketAddressTag ()
{
}
void
SocketRxAddressTag::SetAddress (Address addr)
SocketAddressTag::SetAddress (Address addr)
{
m_address = addr;
}
Address
SocketRxAddressTag::GetAddress (void) const
SocketAddressTag::GetAddress (void) const
{
return m_address;
}
TypeId
SocketRxAddressTag::GetTypeId (void)
SocketAddressTag::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::SocketRxAddressTag")
static TypeId tid = TypeId ("ns3::SocketAddressTag")
.SetParent<Tag> ()
.AddConstructor<SocketRxAddressTag> ()
.AddConstructor<SocketAddressTag> ()
;
return tid;
}
TypeId
SocketRxAddressTag::GetInstanceTypeId (void) const
SocketAddressTag::GetInstanceTypeId (void) const
{
return GetTypeId ();
}
uint32_t
SocketRxAddressTag::GetSerializedSize (void) const
SocketAddressTag::GetSerializedSize (void) const
{
return m_address.GetSerializedSize ();
}
void
SocketRxAddressTag::Serialize (TagBuffer i) const
SocketAddressTag::Serialize (TagBuffer i) const
{
m_address.Serialize (i);
}
void
SocketRxAddressTag::Deserialize (TagBuffer i)
SocketAddressTag::Deserialize (TagBuffer i)
{
m_address.Deserialize (i);
}
void
SocketRxAddressTag::Print (std::ostream &os) const
SocketAddressTag::Print (std::ostream &os) const
{
os << "address=" << m_address;
}
@@ -386,4 +416,5 @@ SocketIpTtlTag::Print (std::ostream &os) const
os << "Ttl=" << (uint32_t) m_ttl;
}
}//namespace ns3

View File

@@ -92,27 +92,22 @@ public:
* \param tid The TypeId of the socket to create
*/
static Ptr<Socket> CreateSocket (Ptr<Node> node, TypeId tid);
/**
* \return the errno associated to the last call which failed in this
* socket. Each socket's errno is initialized to zero
* when the socket is created.
*/
virtual enum Socket::SocketErrno GetErrno (void) const = 0;
/**
* \returns the node this socket is associated with.
*/
virtual Ptr<Node> GetNode (void) const = 0;
void SetCloseUnblocksCallback (Callback<void, Ptr<Socket> > closeUnblocks);
/**
* \param closeCompleted Callback invoked when the close operation is
* completed.
*/
void SetCloseCallback (Callback<void, Ptr<Socket> > closeCompleted);
/**
* \param connectionSucceeded this callback is invoked when the
* connection request initiated by the user is successfully
@@ -165,7 +160,8 @@ public:
* user should check this return value to confirm that the
* callback is supported.
*/
virtual bool SetDataSentCallback (Callback<void, Ptr<Socket>, uint32_t> dataSent);
virtual bool SetDataSentCallback (Callback<void, Ptr<Socket>,
uint32_t> dataSent);
/**
* \brief Notify application when space in transmit buffer is added
*
@@ -241,13 +237,27 @@ public:
*/
virtual int Listen (uint32_t queueLimit) = 0;
/**
* \brief Returns the number of bytes which can be sent in a single call
* to Send.
*
* For datagram sockets, this returns the number of bytes that
* can be passed atomically through the underlying protocol.
*
* For stream sockets, this returns the available space in bytes
* left in the transmit buffer.
*/
virtual uint32_t GetTxAvailable (void) const = 0;
/**
* \brief Send data (or dummy data) to the remote host
*
* This function matches closely in semantics to the send() function
* call in the standard C library (libc):
* ssize_t send (int s, const void *msg, size_t len, int flags);
* except that the function call is asynchronous.
* except that the send I/O is asynchronous. This is the
* primary Send method at this low-level API and must be implemented
* by subclasses.
*
* In a typical blocking sockets model, this call would block upon
* lack of space to hold the message to be sent. In ns-3 at this
@@ -272,96 +282,231 @@ public:
* split the Packet (based on information obtained from
* GetTxAvailable) and reattempt to send the data.
*
* The flags argument is formed by or'ing one or more of the values:
* MSG_OOB process out-of-band data
* MSG_DONTROUTE bypass routing, use direct interface
* These flags are _unsupported_ as of ns-3.1.
*
* \param p ns3::Packet to send
* \param flags Socket control flags
* \returns the number of bytes accepted for transmission if no error
* occurs, and -1 otherwise.
*/
virtual int Send (Ptr<Packet> p) = 0;
/**
* \brief Returns the number of bytes which can be sent in a single call
* to Send.
*
* For datagram sockets, this returns the number of bytes that
* can be passed atomically through the underlying protocol.
*
* For stream sockets, this returns the available space in bytes
* left in the transmit buffer.
* \see SetSendCallback
*/
virtual uint32_t GetTxAvailable (void) const = 0;
virtual int Send (Ptr<Packet> p, uint32_t flags) = 0;
/**
* \brief Send data (or dummy data) to the remote host
* \param buf A pointer to a raw byte buffer of some data to send. If this
* is 0, we send dummy data whose size is specified by the second parameter
* \param size the number of bytes to copy from the buffer
*
* This is provided so as to have an API which is closer in appearance
* to that of real network or BSD sockets.
*/
int Send (const uint8_t* buf, uint32_t size);
/**
* \brief Send data to a specified peer.
*
* This method has similar semantics to Send () but subclasses may
* want to provide checks on socket state, so the implementation is
* pushed to subclasses.
*
* \param p packet to send
* \param address IP Address of remote host
* \param flags Socket control flags
* \param toAddress IP Address of remote host
* \returns -1 in case of error or the number of bytes copied in the
* internal buffer and accepted for transmission.
*/
virtual int SendTo (Ptr<Packet> p, const Address &address) = 0;
virtual int SendTo (Ptr<Packet> p, uint32_t flags,
const Address &toAddress) = 0;
/**
* \brief Send data to a specified peer.
* \param buf A pointer to a raw byte buffer of some data to send. If this
* is 0, we send dummy data whose size is specified by the third parameter
* \param size the number of bytes to copy from the buffer
* \param address IP Address of remote host
* \returns -1 in case of error or the number of bytes copied in the
* internal buffer and accepted for transmission.
*
* This is provided so as to have an API which is closer in appearance
* to that of real network or BSD sockets.
*/
int SendTo (const uint8_t* buf, uint32_t size, const Address &address);
/**
* \brief Read a single packet from the socket
* \param maxSize reader will accept packet up to maxSize
* \param flags Socket recv flags
* \returns Ptr<Packet> of the next in-sequence packet. Returns
* 0 if the socket cannot return a next in-sequence packet conforming
* to the maxSize and flags.
*/
virtual Ptr<Packet> Recv (uint32_t maxSize, uint32_t flags) = 0;
/**
* \brief Read a single packet from the socket
*
* Overloaded version of Recv(maxSize, flags) with maxSize
* implicitly set to maximum sized integer, and flags set to zero.
*
* \returns Ptr<Packet> of the next in-sequence packet. Returns
* 0 if the socket cannot return a next in-sequence packet.
*/
Ptr<Packet> Recv (void);
/**
* \brief Recv data (or dummy data) from the remote host
* \param buf A pointer to a raw byte buffer to write the data to.
* If the underlying packet was carring null (fake) data, this buffer
* will be zeroed up to the length specified by the return value.
* \param size Number of bytes (at most) to copy to buf
* \param flags any flags to pass to the socket
* \returns number of bytes copied into buf
*
* This is provided so as to have an API which is closer in appearance
* to that of real network or BSD sockets.
*/
int Recv (uint8_t* buf, uint32_t size, uint32_t flags);
/**
* Return number of bytes which can be returned from one or
* multiple calls to Recv.
* Must be possible to call this method from the Recv callback.
*/
virtual uint32_t GetRxAvailable (void) const = 0;
/**
* \brief Read data from the socket
*
* This function matches closely in semantics to the recv() function
* call in the standard C library (libc):
* ssize_t recv (int s, void *buf, size_t len, int flags);
* except that the receive I/O is asynchronous. This is the
* primary Recv method at this low-level API and must be implemented
* by subclasses.
*
* This method is normally used only on a connected socket.
* In a typical blocking sockets model, this call would block until
* at least one byte is returned or the connection closes.
* In ns-3 at this API, the call returns immediately in such a case
* and returns 0 if nothing is available to be read.
* However, an application can set a callback, ns3::SetRecvCallback,
* to be notified of data being available to be read
* (when it conceptually unblocks); this is an asynchronous
* I/O model for recv().
*
* This variant of Recv() uses class ns3::Packet to encapsulate
* data, rather than providing a raw pointer and length field.
* This allows an ns-3 application to attach tags if desired (such
* as a flow ID) and may allow the simulator to avoid some data
* copies. Despite the appearance of receiving Packets on a stream
* socket, just think of it as a fancy byte buffer with streaming
* semantics.
*
* The semantics depend on the type of socket. For a datagram socket,
* each Recv() returns the data from at most one Send(), and order
* is not necessarily preserved. For a stream socket, the bytes
* are delivered in order, and on-the-wire packet boundaries are
* not preserved.
*
* The flags argument is formed by or'ing one or more of the values:
* MSG_OOB process out-of-band data
* MSG_PEEK peek at incoming message
* These flags are _unsupported_ as of ns-3.1.
*
* Some variants of Recv() are supported as additional API,
* including RecvFrom(), overloaded Recv() without arguments,
* and variants that use raw character buffers.
*
* \param maxSize reader will accept packet up to maxSize
* \param flags Socket control flags
* \returns Ptr<Packet> of the next in-sequence packet. Returns
* 0 if the socket cannot return a next in-sequence packet conforming
* to the maxSize and flags.
*
* \see SetRecvCallback
*/
virtual Ptr<Packet> Recv (uint32_t maxSize, uint32_t flags) = 0;
/**
* \brief Read a single packet from the socket and retrieve the sender
* address.
*
* Calls Recv(maxSize, flags) with maxSize
* implicitly set to maximum sized integer, and flags set to zero.
*
* This method has similar semantics to Recv () but subclasses may
* want to provide checks on socket state, so the implementation is
* pushed to subclasses.
*
* \param maxSize reader will accept packet up to maxSize
* \param flags Socket control flags
* \param fromAddress output parameter that will return the
* address of the sender of the received packet, if any. Remains
* untouched if no packet is received.
* \returns Ptr<Packet> of the next in-sequence packet. Returns
* 0 if the socket cannot return a next in-sequence packet.
*/
virtual Ptr<Packet> RecvFrom (uint32_t maxSize, uint32_t flags,
Address &fromAddress) = 0;
/////////////////////////////////////////////////////////////////////
// The remainder of these public methods are overloaded methods //
// or variants of Send() and Recv(), and they are non-virtual //
/////////////////////////////////////////////////////////////////////
/**
* \brief Send data (or dummy data) to the remote host
*
* Overloaded version of Send(..., flags) with flags set to zero.
*
* \param p ns3::Packet to send
* \returns the number of bytes accepted for transmission if no error
* occurs, and -1 otherwise.
*/
int Send (Ptr<Packet> p);
/**
* \brief Send data (or dummy data) to the remote host
*
* This method is provided so as to have an API which is closer in
* appearance to that of real network or BSD sockets.
*
* \param buf A pointer to a raw byte buffer of some data to send. If
* this buffer is 0, we send dummy data whose size is specified by the
* second parameter
* \param size the number of bytes to copy from the buffer
* \param flags Socket control flags
*/
int Send (const uint8_t* buf, uint32_t size, uint32_t flags);
/**
* \brief Send data to a specified peer.
*
* This method is provided so as to have an API which is closer in
* appearance to that of real network or BSD sockets.
*
* \param buf A pointer to a raw byte buffer of some data to send.
* If this is 0, we send dummy data whose size is specified by the
* third parameter
* \param size the number of bytes to copy from the buffer
* \param flags Socket control flags
* \param address IP Address of remote host
* \returns -1 in case of error or the number of bytes copied in the
* internal buffer and accepted for transmission.
*
*/
int SendTo (const uint8_t* buf, uint32_t size, uint32_t flags,
const Address &address);
/**
* \brief Read a single packet from the socket
*
* Overloaded version of Recv(maxSize, flags) with maxSize
* implicitly set to maximum sized integer, and flags set to zero.
*
* \returns Ptr<Packet> of the next in-sequence packet. Returns
* 0 if the socket cannot return a next in-sequence packet.
*/
Ptr<Packet> Recv (void);
/**
* \brief Recv data (or dummy data) from the remote host
*
* This method is provided so as to have an API which is closer in
* appearance to that of real network or BSD sockets.
*
* If the underlying packet was carring null (fake) data, this buffer
* will be zeroed up to the length specified by the return value.
*
* \param buf A pointer to a raw byte buffer to write the data to.
* \param size Number of bytes (at most) to copy to buf
* \param flags any flags to pass to the socket
* \returns number of bytes copied into buf
*/
int Recv (uint8_t* buf, uint32_t size, uint32_t flags);
/**
* \brief Read a single packet from the socket and retrieve the sender
* address.
*
* Calls RecvFrom (maxSize, flags, fromAddress) with maxSize
* implicitly set to maximum sized integer, and flags set to zero.
*
* \param maxSize reader will accept packet up to maxSize
* \param flags Socket control flags
* \param fromAddress output parameter that will return the
* address of the sender of the received packet, if any. Remains
* untouched if no packet is received.
* \returns Ptr<Packet> of the next in-sequence packet. Returns
* 0 if the socket cannot return a next in-sequence packet.
*/
Ptr<Packet> RecvFrom (Address &fromAddress);
/**
* \brief Read a single packet from the socket and retrieve the sender
* address.
*
* This method is provided so as to have an API which is closer in
* appearance to that of real network or BSD sockets.
*
* \param buf A pointer to a raw byte buffer to write the data to.
* If the underlying packet was carring null (fake) data, this buffer
* will be zeroed up to the length specified by the return value.
* \param size Number of bytes (at most) to copy to buf
* \param flags any flags to pass to the socket
* \param fromAddress output parameter that will return the
* address of the sender of the received packet, if any. Remains
* untouched if no packet is received.
* \returns number of bytes copied into buf
*/
int RecvFrom (uint8_t* buf, uint32_t size, uint32_t flags,
Address &fromAddress);
protected:
void NotifyCloseUnblocks (void);
@@ -391,13 +536,13 @@ protected:
};
/**
* \brief This class implements a tag that carries the source address
* of a packet across the receiving socket interface.
* \brief This class implements a tag that carries an address
* of a packet across the socket interface.
*/
class SocketRxAddressTag : public Tag
class SocketAddressTag : public Tag
{
public:
SocketRxAddressTag ();
SocketAddressTag ();
void SetAddress (Address addr);
Address GetAddress (void) const;

View File

@@ -58,11 +58,15 @@ public:
virtual int ShutdownSend (void) = 0;
virtual int ShutdownRecv (void) = 0;
virtual int Connect (const Address &address) = 0;
virtual int Send (Ptr<Packet> p) = 0;
virtual uint32_t GetTxAvailable (void) const = 0;
virtual int SendTo (Ptr<Packet> p, const Address &address) = 0;
virtual Ptr<Packet> Recv (uint32_t maxSize, uint32_t flags) = 0;
virtual int Send (Ptr<Packet> p, uint32_t flags) = 0;
virtual int SendTo (Ptr<Packet> p, uint32_t flags,
const Address &toAddress) = 0;
virtual uint32_t GetRxAvailable (void) const = 0;
virtual Ptr<Packet> Recv (uint32_t maxSize, uint32_t flags) = 0;
virtual Ptr<Packet> RecvFrom (uint32_t maxSize, uint32_t flags,
Address &fromAddress) = 0;
private:
// Indirect the attribute setting and getting through private virtual methods

View File

@@ -57,11 +57,14 @@ public:
virtual int ShutdownSend (void) = 0;
virtual int ShutdownRecv (void) = 0;
virtual int Connect (const Address &address) = 0;
virtual int Send (Ptr<Packet> p) = 0;
virtual uint32_t GetTxAvailable (void) const = 0;
virtual int SendTo (Ptr<Packet> p, const Address &address) = 0;
virtual Ptr<Packet> Recv (uint32_t maxSize, uint32_t flags) = 0;
virtual int Send (Ptr<Packet> p, uint32_t flags) = 0;
virtual int SendTo (Ptr<Packet> p, uint32_t flags,
const Address &toAddress) = 0;
virtual uint32_t GetRxAvailable (void) const = 0;
virtual Ptr<Packet> Recv (uint32_t maxSize, uint32_t flags) = 0;
virtual Ptr<Packet> RecvFrom (uint32_t maxSize, uint32_t flags,
Address &fromAddress) = 0;
private:
// Indirect the attribute setting and getting through private virtual methods

View File

@@ -303,13 +303,8 @@ void
AgentImpl::RecvOlsr (Ptr<Socket> socket)
{
Ptr<Packet> receivedPacket;
receivedPacket = socket->Recv ();
SocketRxAddressTag tag;
bool found;
found = receivedPacket->FindFirstMatchingTag (tag);
NS_ASSERT (found);
Address sourceAddress = tag.GetAddress ();
Address sourceAddress;
receivedPacket = socket->RecvFrom (sourceAddress);
InetSocketAddress inetSourceAddr = InetSocketAddress::ConvertFrom (sourceAddress);
Ipv4Address senderIfaceAddr = inetSourceAddr.GetIpv4 ();