blob: 9f2498685aebb15833506c1a3202c4fb9ea247a8 [file] [log] [blame]
Alexander Afanasyevf4e24522013-06-24 14:11:57 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2/*
3 * Copyright (c) 2013 University of California, Los Angeles
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
19 *
20 */
21
Alexander Afanasyev0c395372014-12-20 15:54:02 -080022#include "ndn-tcp-face.hpp"
23#include "ndn-ip-face-stack.hpp"
Alexander Afanasyevd573af22013-07-27 12:57:08 -070024
Alexander Afanasyev0c395372014-12-20 15:54:02 -080025#include "ns3/ndn-l3-protocol.hpp"
Alexander Afanasyevf4e24522013-06-24 14:11:57 -070026
27#include "ns3/log.h"
28#include "ns3/packet.h"
29#include "ns3/node.h"
30#include "ns3/pointer.h"
31#include "ns3/tcp-socket-factory.h"
32
Alexander Afanasyevf4e24522013-06-24 14:11:57 -070033using namespace std;
34
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080035NS_LOG_COMPONENT_DEFINE("ndn.TcpFace");
Alexander Afanasyevf4e24522013-06-24 14:11:57 -070036
37namespace ns3 {
38namespace ndn {
39
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080040class TcpBoundaryHeader : public Header {
Alexander Afanasyevf4e24522013-06-24 14:11:57 -070041public:
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080042 static TypeId
43 GetTypeId(void)
Alexander Afanasyevf4e24522013-06-24 14:11:57 -070044 {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080045 static TypeId tid =
46 TypeId("ns3::ndn::TcpFace::BoundaryHeader").SetGroupName("Ndn").SetParent<Header>();
Alexander Afanasyevf4e24522013-06-24 14:11:57 -070047 return tid;
48 }
49
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080050 TcpBoundaryHeader()
51 : m_length(0)
Alexander Afanasyevf4e24522013-06-24 14:11:57 -070052 {
53 }
Alexander Afanasyevf4e24522013-06-24 14:11:57 -070054
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080055 TcpBoundaryHeader(Ptr<Packet> packet)
56 : m_length(packet->GetSize())
57 {
58 }
59
60 TcpBoundaryHeader(uint32_t length)
61 : m_length(length)
Alexander Afanasyevf4e24522013-06-24 14:11:57 -070062 {
63 }
64
65 uint32_t
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080066 GetLength() const
Alexander Afanasyevf4e24522013-06-24 14:11:57 -070067 {
68 return m_length;
69 }
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080070
Alexander Afanasyevf4e24522013-06-24 14:11:57 -070071 virtual TypeId
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080072 GetInstanceTypeId(void) const
Alexander Afanasyevf4e24522013-06-24 14:11:57 -070073 {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080074 return TcpBoundaryHeader::GetTypeId();
Alexander Afanasyevf4e24522013-06-24 14:11:57 -070075 }
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080076
Alexander Afanasyevf4e24522013-06-24 14:11:57 -070077 virtual void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080078 Print(std::ostream& os) const
Alexander Afanasyevf4e24522013-06-24 14:11:57 -070079 {
80 os << "[" << m_length << "]";
81 }
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080082
Alexander Afanasyevf4e24522013-06-24 14:11:57 -070083 virtual uint32_t
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080084 GetSerializedSize(void) const
Alexander Afanasyevf4e24522013-06-24 14:11:57 -070085 {
86 return 4;
87 }
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080088
Alexander Afanasyevf4e24522013-06-24 14:11:57 -070089 virtual void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080090 Serialize(Buffer::Iterator start) const
Alexander Afanasyevf4e24522013-06-24 14:11:57 -070091 {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080092 start.WriteU32(m_length);
Alexander Afanasyevf4e24522013-06-24 14:11:57 -070093 }
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080094
Alexander Afanasyevf4e24522013-06-24 14:11:57 -070095 virtual uint32_t
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080096 Deserialize(Buffer::Iterator start)
Alexander Afanasyevf4e24522013-06-24 14:11:57 -070097 {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080098 m_length = start.ReadU32();
Alexander Afanasyevf4e24522013-06-24 14:11:57 -070099 return 4;
100 }
101
102private:
103 uint32_t m_length;
104};
105
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800106NS_OBJECT_ENSURE_REGISTERED(TcpFace);
Alexander Afanasyevf4e24522013-06-24 14:11:57 -0700107
108TypeId
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800109TcpFace::GetTypeId()
Alexander Afanasyevf4e24522013-06-24 14:11:57 -0700110{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800111 static TypeId tid = TypeId("ns3::ndn::TcpFace").SetParent<Face>().SetGroupName("Ndn");
Alexander Afanasyevf4e24522013-06-24 14:11:57 -0700112 return tid;
113}
114
115/**
116 * By default, Ndn face are created in the "down" state. Before
117 * becoming useable, the user must invoke SetUp on the face
118 */
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800119TcpFace::TcpFace(Ptr<Node> node, Ptr<Socket> socket, Ipv4Address address)
120 : Face(node)
121 , m_socket(socket)
122 , m_address(address)
123 , m_pendingPacketLength(0)
Alexander Afanasyevf4e24522013-06-24 14:11:57 -0700124{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800125 SetMetric(1); // default metric
Alexander Afanasyevf4e24522013-06-24 14:11:57 -0700126}
127
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800128TcpFace::~TcpFace()
Alexander Afanasyevf4e24522013-06-24 14:11:57 -0700129{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800130 NS_LOG_FUNCTION_NOARGS();
Alexander Afanasyevf4e24522013-06-24 14:11:57 -0700131}
132
133TcpFace& TcpFace::operator= (const TcpFace &)
134{
135 return *this;
136}
137
138void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800139TcpFace::RegisterProtocolHandlers(const InterestHandler& interestHandler,
140 const DataHandler& dataHandler)
Alexander Afanasyevf4e24522013-06-24 14:11:57 -0700141{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800142 NS_LOG_FUNCTION(this);
Alexander Afanasyevf4e24522013-06-24 14:11:57 -0700143
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800144 Face::RegisterProtocolHandlers(interestHandler, dataHandler);
145 m_socket->SetRecvCallback(MakeCallback(&TcpFace::ReceiveFromTcp, this));
Alexander Afanasyevf4e24522013-06-24 14:11:57 -0700146}
147
Alexander Afanasyevaa84fae2013-07-27 12:01:37 -0700148void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800149TcpFace::UnRegisterProtocolHandlers()
Alexander Afanasyevf4e24522013-06-24 14:11:57 -0700150{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800151 m_socket->SetRecvCallback(MakeNullCallback<void, Ptr<Socket>>());
152 Face::UnRegisterProtocolHandlers();
Alexander Afanasyevaa84fae2013-07-27 12:01:37 -0700153}
154
155bool
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800156TcpFace::Send(Ptr<Packet> packet)
Alexander Afanasyevaa84fae2013-07-27 12:01:37 -0700157{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800158 if (!Face::Send(packet)) {
159 return false;
160 }
Alexander Afanasyevaa84fae2013-07-27 12:01:37 -0700161
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800162 NS_LOG_FUNCTION(this << packet);
163
164 Ptr<Packet> boundary = Create<Packet>();
165 TcpBoundaryHeader hdr(packet);
166 boundary->AddHeader(hdr);
167
168 m_socket->Send(boundary);
169 m_socket->Send(packet);
Alexander Afanasyevf4e24522013-06-24 14:11:57 -0700170
171 return true;
172}
173
174void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800175TcpFace::ReceiveFromTcp(Ptr<Socket> clientSocket)
Alexander Afanasyevf4e24522013-06-24 14:11:57 -0700176{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800177 NS_LOG_FUNCTION(this << clientSocket);
Alexander Afanasyevf4e24522013-06-24 14:11:57 -0700178 TcpBoundaryHeader hdr;
179
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800180 if (m_pendingPacketLength > 0) {
181 if (clientSocket->GetRxAvailable() >= m_pendingPacketLength) {
182 Ptr<Packet> realPacket = clientSocket->Recv(m_pendingPacketLength, 0);
183 NS_LOG_DEBUG("+++ Expected " << m_pendingPacketLength << " bytes, got "
184 << realPacket->GetSize() << " bytes");
185 if (realPacket == 0)
186 return;
187
188 Receive(realPacket);
Alexander Afanasyevf4e24522013-06-24 14:11:57 -0700189 }
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800190 else
191 return; // still not ready
192 }
193
Alexander Afanasyevf4e24522013-06-24 14:11:57 -0700194 m_pendingPacketLength = 0;
Alexander Afanasyevf4e24522013-06-24 14:11:57 -0700195
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800196 while (clientSocket->GetRxAvailable() >= hdr.GetSerializedSize()) {
197 Ptr<Packet> boundary = clientSocket->Recv(hdr.GetSerializedSize(), 0);
198 if (boundary == 0)
199 return; // no idea why it would happen...
Alexander Afanasyevf4e24522013-06-24 14:11:57 -0700200
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800201 NS_LOG_DEBUG("Expected 4 bytes, got " << boundary->GetSize() << " bytes");
202
203 boundary->RemoveHeader(hdr);
204 NS_LOG_DEBUG("Header specifies length: " << hdr.GetLength());
205 m_pendingPacketLength = hdr.GetLength();
206
207 if (clientSocket->GetRxAvailable() >= hdr.GetLength()) {
208 Ptr<Packet> realPacket = clientSocket->Recv(hdr.GetLength(), 0);
209 if (realPacket == 0) {
210 NS_LOG_DEBUG("Got nothing, but requested at least " << hdr.GetLength());
211 return;
212 }
213
214 NS_LOG_DEBUG("Receiving data " << hdr.GetLength() << " bytes, got " << realPacket->GetSize()
215 << " bytes");
216
217 Receive(realPacket);
218 m_pendingPacketLength = 0;
Alexander Afanasyevf4e24522013-06-24 14:11:57 -0700219 }
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800220 else {
221 return;
222 }
223 }
Alexander Afanasyevf4e24522013-06-24 14:11:57 -0700224}
225
226void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800227TcpFace::OnTcpConnectionClosed(Ptr<Socket> socket)
Alexander Afanasyevf4e24522013-06-24 14:11:57 -0700228{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800229 NS_LOG_FUNCTION(this << socket);
230 GetNode()->GetObject<IpFaceStack>()->DestroyTcpFace(this);
Alexander Afanasyevf4e24522013-06-24 14:11:57 -0700231}
232
233Ipv4Address
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800234TcpFace::GetAddress() const
Alexander Afanasyevf4e24522013-06-24 14:11:57 -0700235{
236 return m_address;
237}
238
Alexander Afanasyevf4e24522013-06-24 14:11:57 -0700239void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800240TcpFace::SetCreateCallback(Callback<void, Ptr<Face>> callback)
Alexander Afanasyevaa84fae2013-07-27 12:01:37 -0700241{
242 m_onCreateCallback = callback;
243}
244
245void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800246TcpFace::OnConnect(Ptr<Socket> socket)
Alexander Afanasyevf4e24522013-06-24 14:11:57 -0700247{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800248 NS_LOG_FUNCTION(this << socket);
Alexander Afanasyevf4e24522013-06-24 14:11:57 -0700249
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800250 Ptr<L3Protocol> ndn = GetNode()->GetObject<L3Protocol>();
Alexander Afanasyevf4e24522013-06-24 14:11:57 -0700251
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800252 ndn->AddFace(this);
253 this->SetUp(true);
Alexander Afanasyevaa84fae2013-07-27 12:01:37 -0700254
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800255 socket->SetCloseCallbacks(MakeCallback(&TcpFace::OnTcpConnectionClosed, this),
256 MakeCallback(&TcpFace::OnTcpConnectionClosed, this));
257
258 if (!m_onCreateCallback.IsNull()) {
259 m_onCreateCallback(this);
260 m_onCreateCallback = IpFaceStack::NULL_CREATE_CALLBACK;
261 }
Alexander Afanasyevf4e24522013-06-24 14:11:57 -0700262}
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800263
Alexander Afanasyevf4e24522013-06-24 14:11:57 -0700264std::ostream&
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800265TcpFace::Print(std::ostream& os) const
Alexander Afanasyevf4e24522013-06-24 14:11:57 -0700266{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800267 os << "dev=tcp(" << GetId() << ", " << m_address << ")";
Alexander Afanasyevf4e24522013-06-24 14:11:57 -0700268 return os;
269}
270
271} // namespace ndn
272} // namespace ns3