blob: 701ad64e78efeb34315c9c2d9306e2dfd88e62de [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 Afanasyev0c395372014-12-20 15:54:02 -080033#include "ns3/ndn-name.hpp"
Alexander Afanasyevf4e24522013-06-24 14:11:57 -070034
35using namespace std;
36
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080037NS_LOG_COMPONENT_DEFINE("ndn.TcpFace");
Alexander Afanasyevf4e24522013-06-24 14:11:57 -070038
39namespace ns3 {
40namespace ndn {
41
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080042class TcpBoundaryHeader : public Header {
Alexander Afanasyevf4e24522013-06-24 14:11:57 -070043public:
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080044 static TypeId
45 GetTypeId(void)
Alexander Afanasyevf4e24522013-06-24 14:11:57 -070046 {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080047 static TypeId tid =
48 TypeId("ns3::ndn::TcpFace::BoundaryHeader").SetGroupName("Ndn").SetParent<Header>();
Alexander Afanasyevf4e24522013-06-24 14:11:57 -070049 return tid;
50 }
51
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080052 TcpBoundaryHeader()
53 : m_length(0)
Alexander Afanasyevf4e24522013-06-24 14:11:57 -070054 {
55 }
Alexander Afanasyevf4e24522013-06-24 14:11:57 -070056
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080057 TcpBoundaryHeader(Ptr<Packet> packet)
58 : m_length(packet->GetSize())
59 {
60 }
61
62 TcpBoundaryHeader(uint32_t length)
63 : m_length(length)
Alexander Afanasyevf4e24522013-06-24 14:11:57 -070064 {
65 }
66
67 uint32_t
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080068 GetLength() const
Alexander Afanasyevf4e24522013-06-24 14:11:57 -070069 {
70 return m_length;
71 }
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080072
Alexander Afanasyevf4e24522013-06-24 14:11:57 -070073 virtual TypeId
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080074 GetInstanceTypeId(void) const
Alexander Afanasyevf4e24522013-06-24 14:11:57 -070075 {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080076 return TcpBoundaryHeader::GetTypeId();
Alexander Afanasyevf4e24522013-06-24 14:11:57 -070077 }
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080078
Alexander Afanasyevf4e24522013-06-24 14:11:57 -070079 virtual void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080080 Print(std::ostream& os) const
Alexander Afanasyevf4e24522013-06-24 14:11:57 -070081 {
82 os << "[" << m_length << "]";
83 }
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080084
Alexander Afanasyevf4e24522013-06-24 14:11:57 -070085 virtual uint32_t
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080086 GetSerializedSize(void) const
Alexander Afanasyevf4e24522013-06-24 14:11:57 -070087 {
88 return 4;
89 }
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080090
Alexander Afanasyevf4e24522013-06-24 14:11:57 -070091 virtual void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080092 Serialize(Buffer::Iterator start) const
Alexander Afanasyevf4e24522013-06-24 14:11:57 -070093 {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080094 start.WriteU32(m_length);
Alexander Afanasyevf4e24522013-06-24 14:11:57 -070095 }
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080096
Alexander Afanasyevf4e24522013-06-24 14:11:57 -070097 virtual uint32_t
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080098 Deserialize(Buffer::Iterator start)
Alexander Afanasyevf4e24522013-06-24 14:11:57 -070099 {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800100 m_length = start.ReadU32();
Alexander Afanasyevf4e24522013-06-24 14:11:57 -0700101 return 4;
102 }
103
104private:
105 uint32_t m_length;
106};
107
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800108NS_OBJECT_ENSURE_REGISTERED(TcpFace);
Alexander Afanasyevf4e24522013-06-24 14:11:57 -0700109
110TypeId
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800111TcpFace::GetTypeId()
Alexander Afanasyevf4e24522013-06-24 14:11:57 -0700112{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800113 static TypeId tid = TypeId("ns3::ndn::TcpFace").SetParent<Face>().SetGroupName("Ndn");
Alexander Afanasyevf4e24522013-06-24 14:11:57 -0700114 return tid;
115}
116
117/**
118 * By default, Ndn face are created in the "down" state. Before
119 * becoming useable, the user must invoke SetUp on the face
120 */
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800121TcpFace::TcpFace(Ptr<Node> node, Ptr<Socket> socket, Ipv4Address address)
122 : Face(node)
123 , m_socket(socket)
124 , m_address(address)
125 , m_pendingPacketLength(0)
Alexander Afanasyevf4e24522013-06-24 14:11:57 -0700126{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800127 SetMetric(1); // default metric
Alexander Afanasyevf4e24522013-06-24 14:11:57 -0700128}
129
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800130TcpFace::~TcpFace()
Alexander Afanasyevf4e24522013-06-24 14:11:57 -0700131{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800132 NS_LOG_FUNCTION_NOARGS();
Alexander Afanasyevf4e24522013-06-24 14:11:57 -0700133}
134
135TcpFace& TcpFace::operator= (const TcpFace &)
136{
137 return *this;
138}
139
140void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800141TcpFace::RegisterProtocolHandlers(const InterestHandler& interestHandler,
142 const DataHandler& dataHandler)
Alexander Afanasyevf4e24522013-06-24 14:11:57 -0700143{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800144 NS_LOG_FUNCTION(this);
Alexander Afanasyevf4e24522013-06-24 14:11:57 -0700145
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800146 Face::RegisterProtocolHandlers(interestHandler, dataHandler);
147 m_socket->SetRecvCallback(MakeCallback(&TcpFace::ReceiveFromTcp, this));
Alexander Afanasyevf4e24522013-06-24 14:11:57 -0700148}
149
Alexander Afanasyevaa84fae2013-07-27 12:01:37 -0700150void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800151TcpFace::UnRegisterProtocolHandlers()
Alexander Afanasyevf4e24522013-06-24 14:11:57 -0700152{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800153 m_socket->SetRecvCallback(MakeNullCallback<void, Ptr<Socket>>());
154 Face::UnRegisterProtocolHandlers();
Alexander Afanasyevaa84fae2013-07-27 12:01:37 -0700155}
156
157bool
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800158TcpFace::Send(Ptr<Packet> packet)
Alexander Afanasyevaa84fae2013-07-27 12:01:37 -0700159{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800160 if (!Face::Send(packet)) {
161 return false;
162 }
Alexander Afanasyevaa84fae2013-07-27 12:01:37 -0700163
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800164 NS_LOG_FUNCTION(this << packet);
165
166 Ptr<Packet> boundary = Create<Packet>();
167 TcpBoundaryHeader hdr(packet);
168 boundary->AddHeader(hdr);
169
170 m_socket->Send(boundary);
171 m_socket->Send(packet);
Alexander Afanasyevf4e24522013-06-24 14:11:57 -0700172
173 return true;
174}
175
176void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800177TcpFace::ReceiveFromTcp(Ptr<Socket> clientSocket)
Alexander Afanasyevf4e24522013-06-24 14:11:57 -0700178{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800179 NS_LOG_FUNCTION(this << clientSocket);
Alexander Afanasyevf4e24522013-06-24 14:11:57 -0700180 TcpBoundaryHeader hdr;
181
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800182 if (m_pendingPacketLength > 0) {
183 if (clientSocket->GetRxAvailable() >= m_pendingPacketLength) {
184 Ptr<Packet> realPacket = clientSocket->Recv(m_pendingPacketLength, 0);
185 NS_LOG_DEBUG("+++ Expected " << m_pendingPacketLength << " bytes, got "
186 << realPacket->GetSize() << " bytes");
187 if (realPacket == 0)
188 return;
189
190 Receive(realPacket);
Alexander Afanasyevf4e24522013-06-24 14:11:57 -0700191 }
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800192 else
193 return; // still not ready
194 }
195
Alexander Afanasyevf4e24522013-06-24 14:11:57 -0700196 m_pendingPacketLength = 0;
Alexander Afanasyevf4e24522013-06-24 14:11:57 -0700197
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800198 while (clientSocket->GetRxAvailable() >= hdr.GetSerializedSize()) {
199 Ptr<Packet> boundary = clientSocket->Recv(hdr.GetSerializedSize(), 0);
200 if (boundary == 0)
201 return; // no idea why it would happen...
Alexander Afanasyevf4e24522013-06-24 14:11:57 -0700202
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800203 NS_LOG_DEBUG("Expected 4 bytes, got " << boundary->GetSize() << " bytes");
204
205 boundary->RemoveHeader(hdr);
206 NS_LOG_DEBUG("Header specifies length: " << hdr.GetLength());
207 m_pendingPacketLength = hdr.GetLength();
208
209 if (clientSocket->GetRxAvailable() >= hdr.GetLength()) {
210 Ptr<Packet> realPacket = clientSocket->Recv(hdr.GetLength(), 0);
211 if (realPacket == 0) {
212 NS_LOG_DEBUG("Got nothing, but requested at least " << hdr.GetLength());
213 return;
214 }
215
216 NS_LOG_DEBUG("Receiving data " << hdr.GetLength() << " bytes, got " << realPacket->GetSize()
217 << " bytes");
218
219 Receive(realPacket);
220 m_pendingPacketLength = 0;
Alexander Afanasyevf4e24522013-06-24 14:11:57 -0700221 }
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800222 else {
223 return;
224 }
225 }
Alexander Afanasyevf4e24522013-06-24 14:11:57 -0700226}
227
228void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800229TcpFace::OnTcpConnectionClosed(Ptr<Socket> socket)
Alexander Afanasyevf4e24522013-06-24 14:11:57 -0700230{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800231 NS_LOG_FUNCTION(this << socket);
232 GetNode()->GetObject<IpFaceStack>()->DestroyTcpFace(this);
Alexander Afanasyevf4e24522013-06-24 14:11:57 -0700233}
234
235Ipv4Address
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800236TcpFace::GetAddress() const
Alexander Afanasyevf4e24522013-06-24 14:11:57 -0700237{
238 return m_address;
239}
240
Alexander Afanasyevf4e24522013-06-24 14:11:57 -0700241void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800242TcpFace::SetCreateCallback(Callback<void, Ptr<Face>> callback)
Alexander Afanasyevaa84fae2013-07-27 12:01:37 -0700243{
244 m_onCreateCallback = callback;
245}
246
247void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800248TcpFace::OnConnect(Ptr<Socket> socket)
Alexander Afanasyevf4e24522013-06-24 14:11:57 -0700249{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800250 NS_LOG_FUNCTION(this << socket);
Alexander Afanasyevf4e24522013-06-24 14:11:57 -0700251
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800252 Ptr<L3Protocol> ndn = GetNode()->GetObject<L3Protocol>();
Alexander Afanasyevf4e24522013-06-24 14:11:57 -0700253
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800254 ndn->AddFace(this);
255 this->SetUp(true);
Alexander Afanasyevaa84fae2013-07-27 12:01:37 -0700256
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800257 socket->SetCloseCallbacks(MakeCallback(&TcpFace::OnTcpConnectionClosed, this),
258 MakeCallback(&TcpFace::OnTcpConnectionClosed, this));
259
260 if (!m_onCreateCallback.IsNull()) {
261 m_onCreateCallback(this);
262 m_onCreateCallback = IpFaceStack::NULL_CREATE_CALLBACK;
263 }
Alexander Afanasyevf4e24522013-06-24 14:11:57 -0700264}
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800265
Alexander Afanasyevf4e24522013-06-24 14:11:57 -0700266std::ostream&
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800267TcpFace::Print(std::ostream& os) const
Alexander Afanasyevf4e24522013-06-24 14:11:57 -0700268{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800269 os << "dev=tcp(" << GetId() << ", " << m_address << ")";
Alexander Afanasyevf4e24522013-06-24 14:11:57 -0700270 return os;
271}
272
273} // namespace ndn
274} // namespace ns3