Alexander Afanasyev | f4e2452 | 2013-06-24 14:11:57 -0700 | [diff] [blame] | 1 | /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ |
| 2 | /* |
| 3 | * Copyright (c) 2011 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 | |
Alexander Afanasyev | 0c39537 | 2014-12-20 15:54:02 -0800 | [diff] [blame] | 21 | #include "ndn-ip-face-stack.hpp" |
| 22 | #include "ndn-tcp-face.hpp" |
| 23 | #include "ndn-udp-face.hpp" |
Alexander Afanasyev | f4e2452 | 2013-06-24 14:11:57 -0700 | [diff] [blame] | 24 | |
Alexander Afanasyev | 0c39537 | 2014-12-20 15:54:02 -0800 | [diff] [blame] | 25 | #include "ns3/ndn-l3-protocol.hpp" |
Alexander Afanasyev | f4e2452 | 2013-06-24 14:11:57 -0700 | [diff] [blame] | 26 | |
| 27 | #include "ns3/log.h" |
| 28 | #include "ns3/assert.h" |
| 29 | #include "ns3/packet.h" |
Alexander Afanasyev | aa84fae | 2013-07-27 12:01:37 -0700 | [diff] [blame] | 30 | #include "ns3/boolean.h" |
Alexander Afanasyev | f4e2452 | 2013-06-24 14:11:57 -0700 | [diff] [blame] | 31 | |
| 32 | #include "ns3/socket.h" |
| 33 | #include "ns3/tcp-socket-factory.h" |
Alexander Afanasyev | d573af2 | 2013-07-27 12:57:08 -0700 | [diff] [blame] | 34 | #include "ns3/udp-socket-factory.h" |
Alexander Afanasyev | f4e2452 | 2013-06-24 14:11:57 -0700 | [diff] [blame] | 35 | #include "ns3/simulator.h" |
| 36 | |
Alexander Afanasyev | be55cf6 | 2014-12-20 17:51:09 -0800 | [diff] [blame] | 37 | NS_LOG_COMPONENT_DEFINE("ndn.IpFaceStack"); |
Alexander Afanasyev | f4e2452 | 2013-06-24 14:11:57 -0700 | [diff] [blame] | 38 | |
| 39 | namespace ns3 { |
| 40 | namespace ndn { |
Alexander Afanasyev | d573af2 | 2013-07-27 12:57:08 -0700 | [diff] [blame] | 41 | |
Alexander Afanasyev | be55cf6 | 2014-12-20 17:51:09 -0800 | [diff] [blame] | 42 | NS_OBJECT_ENSURE_REGISTERED(IpFaceStack); |
Alexander Afanasyev | f4e2452 | 2013-06-24 14:11:57 -0700 | [diff] [blame] | 43 | |
Alexander Afanasyev | be55cf6 | 2014-12-20 17:51:09 -0800 | [diff] [blame] | 44 | const Callback<void, Ptr<Face>> IpFaceStack::NULL_CREATE_CALLBACK = |
| 45 | MakeNullCallback<void, Ptr<Face>>(); |
Alexander Afanasyev | d573af2 | 2013-07-27 12:57:08 -0700 | [diff] [blame] | 46 | |
Alexander Afanasyev | f4e2452 | 2013-06-24 14:11:57 -0700 | [diff] [blame] | 47 | TypeId |
Alexander Afanasyev | be55cf6 | 2014-12-20 17:51:09 -0800 | [diff] [blame] | 48 | IpFaceStack::GetTypeId(void) |
Alexander Afanasyev | f4e2452 | 2013-06-24 14:11:57 -0700 | [diff] [blame] | 49 | { |
Alexander Afanasyev | be55cf6 | 2014-12-20 17:51:09 -0800 | [diff] [blame] | 50 | static TypeId tid = |
| 51 | TypeId("ns3::ndn::IpFaceStack") |
| 52 | .SetGroupName("Ndn") |
| 53 | .SetParent<Object>() |
| 54 | .AddConstructor<IpFaceStack>() |
Alexander Afanasyev | f4e2452 | 2013-06-24 14:11:57 -0700 | [diff] [blame] | 55 | |
Alexander Afanasyev | be55cf6 | 2014-12-20 17:51:09 -0800 | [diff] [blame] | 56 | .AddAttribute("EnableTCP", "Enable ability to create TCP faces", BooleanValue(true), |
| 57 | MakeBooleanAccessor(&IpFaceStack::m_enableTcp), MakeBooleanChecker()) |
Alexander Afanasyev | f4e2452 | 2013-06-24 14:11:57 -0700 | [diff] [blame] | 58 | |
Alexander Afanasyev | be55cf6 | 2014-12-20 17:51:09 -0800 | [diff] [blame] | 59 | .AddAttribute("EnableUDP", "Enable ability to create UDP faces", BooleanValue(true), |
| 60 | MakeBooleanAccessor(&IpFaceStack::m_enableUdp), MakeBooleanChecker()); |
Alexander Afanasyev | f4e2452 | 2013-06-24 14:11:57 -0700 | [diff] [blame] | 61 | return tid; |
| 62 | } |
Alexander Afanasyev | d573af2 | 2013-07-27 12:57:08 -0700 | [diff] [blame] | 63 | |
Alexander Afanasyev | be55cf6 | 2014-12-20 17:51:09 -0800 | [diff] [blame] | 64 | IpFaceStack::IpFaceStack() |
Alexander Afanasyev | f4e2452 | 2013-06-24 14:11:57 -0700 | [diff] [blame] | 65 | { |
| 66 | } |
Alexander Afanasyev | d573af2 | 2013-07-27 12:57:08 -0700 | [diff] [blame] | 67 | |
Alexander Afanasyev | be55cf6 | 2014-12-20 17:51:09 -0800 | [diff] [blame] | 68 | IpFaceStack::~IpFaceStack() |
Alexander Afanasyev | f4e2452 | 2013-06-24 14:11:57 -0700 | [diff] [blame] | 69 | { |
| 70 | } |
| 71 | |
| 72 | void |
Alexander Afanasyev | be55cf6 | 2014-12-20 17:51:09 -0800 | [diff] [blame] | 73 | IpFaceStack::NotifyNewAggregate() |
Alexander Afanasyev | f4e2452 | 2013-06-24 14:11:57 -0700 | [diff] [blame] | 74 | { |
Alexander Afanasyev | be55cf6 | 2014-12-20 17:51:09 -0800 | [diff] [blame] | 75 | if (m_node == 0) { |
| 76 | m_node = GetObject<Node>(); |
| 77 | if (m_node != 0) { |
| 78 | Simulator::ScheduleWithContext(m_node->GetId(), Seconds(0.1), &IpFaceStack::StartServer, |
| 79 | this); |
Alexander Afanasyev | f4e2452 | 2013-06-24 14:11:57 -0700 | [diff] [blame] | 80 | } |
Alexander Afanasyev | be55cf6 | 2014-12-20 17:51:09 -0800 | [diff] [blame] | 81 | } |
Alexander Afanasyev | f4e2452 | 2013-06-24 14:11:57 -0700 | [diff] [blame] | 82 | } |
| 83 | |
| 84 | // Application Methods |
Alexander Afanasyev | d573af2 | 2013-07-27 12:57:08 -0700 | [diff] [blame] | 85 | void |
Alexander Afanasyev | be55cf6 | 2014-12-20 17:51:09 -0800 | [diff] [blame] | 86 | IpFaceStack::StartServer() // Called at time specified by Start |
Alexander Afanasyev | f4e2452 | 2013-06-24 14:11:57 -0700 | [diff] [blame] | 87 | { |
Alexander Afanasyev | be55cf6 | 2014-12-20 17:51:09 -0800 | [diff] [blame] | 88 | NS_LOG_FUNCTION(this); |
Alexander Afanasyev | d573af2 | 2013-07-27 12:57:08 -0700 | [diff] [blame] | 89 | |
Alexander Afanasyev | be55cf6 | 2014-12-20 17:51:09 -0800 | [diff] [blame] | 90 | if (m_enableTcp) { |
| 91 | m_tcpServer = Socket::CreateSocket(m_node, TcpSocketFactory::GetTypeId()); |
Alexander Afanasyev | d573af2 | 2013-07-27 12:57:08 -0700 | [diff] [blame] | 92 | |
Alexander Afanasyev | be55cf6 | 2014-12-20 17:51:09 -0800 | [diff] [blame] | 93 | m_tcpServer->Bind(InetSocketAddress(Ipv4Address::GetAny(), L3Protocol::IP_STACK_PORT)); |
| 94 | m_tcpServer->Listen(); |
Alexander Afanasyev | f4e2452 | 2013-06-24 14:11:57 -0700 | [diff] [blame] | 95 | |
Alexander Afanasyev | be55cf6 | 2014-12-20 17:51:09 -0800 | [diff] [blame] | 96 | m_tcpServer->SetAcceptCallback(MakeCallback(&IpFaceStack::OnTcpConnectionRequest, this), |
| 97 | MakeCallback(&IpFaceStack::OnTcpConnectionAccept, this)); |
| 98 | } |
Alexander Afanasyev | f4e2452 | 2013-06-24 14:11:57 -0700 | [diff] [blame] | 99 | |
Alexander Afanasyev | be55cf6 | 2014-12-20 17:51:09 -0800 | [diff] [blame] | 100 | if (m_enableUdp) { |
| 101 | m_udpServer = Socket::CreateSocket(m_node, UdpSocketFactory::GetTypeId()); |
| 102 | m_udpServer->Bind(InetSocketAddress(Ipv4Address::GetAny(), L3Protocol::IP_STACK_PORT)); |
Alexander Afanasyev | d573af2 | 2013-07-27 12:57:08 -0700 | [diff] [blame] | 103 | |
Alexander Afanasyev | be55cf6 | 2014-12-20 17:51:09 -0800 | [diff] [blame] | 104 | m_udpServer->SetRecvCallback(MakeCallback(&IpFaceStack::OnUdpPacket, this)); |
| 105 | } |
Alexander Afanasyev | f4e2452 | 2013-06-24 14:11:57 -0700 | [diff] [blame] | 106 | } |
| 107 | |
| 108 | bool |
Alexander Afanasyev | be55cf6 | 2014-12-20 17:51:09 -0800 | [diff] [blame] | 109 | IpFaceStack::OnTcpConnectionRequest(Ptr<Socket> sock, const Address& addr) |
Alexander Afanasyev | f4e2452 | 2013-06-24 14:11:57 -0700 | [diff] [blame] | 110 | { |
Alexander Afanasyev | be55cf6 | 2014-12-20 17:51:09 -0800 | [diff] [blame] | 111 | NS_LOG_FUNCTION(this << sock << InetSocketAddress::ConvertFrom(addr)); |
Alexander Afanasyev | f4e2452 | 2013-06-24 14:11:57 -0700 | [diff] [blame] | 112 | return true; // accept all connections from anybody |
| 113 | } |
| 114 | |
| 115 | void |
Alexander Afanasyev | be55cf6 | 2014-12-20 17:51:09 -0800 | [diff] [blame] | 116 | IpFaceStack::OnTcpConnectionAccept(Ptr<Socket> socket, const Address& addr) |
Alexander Afanasyev | f4e2452 | 2013-06-24 14:11:57 -0700 | [diff] [blame] | 117 | { |
Alexander Afanasyev | be55cf6 | 2014-12-20 17:51:09 -0800 | [diff] [blame] | 118 | NS_LOG_FUNCTION(this << socket << InetSocketAddress::ConvertFrom(addr)); |
Alexander Afanasyev | d573af2 | 2013-07-27 12:57:08 -0700 | [diff] [blame] | 119 | |
Alexander Afanasyev | be55cf6 | 2014-12-20 17:51:09 -0800 | [diff] [blame] | 120 | Ptr<L3Protocol> ndn = m_node->GetObject<L3Protocol>(); |
| 121 | Ptr<TcpFace> face = |
| 122 | CreateObject<TcpFace>(m_node, socket, InetSocketAddress::ConvertFrom(addr).GetIpv4()); |
Alexander Afanasyev | f4e2452 | 2013-06-24 14:11:57 -0700 | [diff] [blame] | 123 | |
Alexander Afanasyev | be55cf6 | 2014-12-20 17:51:09 -0800 | [diff] [blame] | 124 | ndn->AddFace(face); |
| 125 | face->SetUp(true); |
Alexander Afanasyev | f4e2452 | 2013-06-24 14:11:57 -0700 | [diff] [blame] | 126 | |
Alexander Afanasyev | be55cf6 | 2014-12-20 17:51:09 -0800 | [diff] [blame] | 127 | socket->SetCloseCallbacks(MakeCallback(&TcpFace::OnTcpConnectionClosed, face), |
| 128 | MakeCallback(&TcpFace::OnTcpConnectionClosed, face)); |
Alexander Afanasyev | f4e2452 | 2013-06-24 14:11:57 -0700 | [diff] [blame] | 129 | } |
| 130 | |
Alexander Afanasyev | d573af2 | 2013-07-27 12:57:08 -0700 | [diff] [blame] | 131 | void |
Alexander Afanasyev | be55cf6 | 2014-12-20 17:51:09 -0800 | [diff] [blame] | 132 | IpFaceStack::OnUdpPacket(Ptr<Socket> socket) |
Alexander Afanasyev | d573af2 | 2013-07-27 12:57:08 -0700 | [diff] [blame] | 133 | { |
Alexander Afanasyev | be55cf6 | 2014-12-20 17:51:09 -0800 | [diff] [blame] | 134 | NS_LOG_FUNCTION(this << socket); |
Alexander Afanasyev | d573af2 | 2013-07-27 12:57:08 -0700 | [diff] [blame] | 135 | |
| 136 | Ptr<Packet> packet; |
| 137 | Address from; |
Alexander Afanasyev | be55cf6 | 2014-12-20 17:51:09 -0800 | [diff] [blame] | 138 | while ((packet = socket->RecvFrom(from))) { |
| 139 | Ptr<UdpFace> face = CreateOrGetUdpFace(InetSocketAddress::ConvertFrom(from).GetIpv4()); |
| 140 | face->ReceiveFromUdp(packet); |
| 141 | } |
Alexander Afanasyev | d573af2 | 2013-07-27 12:57:08 -0700 | [diff] [blame] | 142 | } |
| 143 | |
| 144 | Ptr<TcpFace> |
Alexander Afanasyev | be55cf6 | 2014-12-20 17:51:09 -0800 | [diff] [blame] | 145 | IpFaceStack::GetTcpFaceByAddress(const Ipv4Address& address) |
Alexander Afanasyev | d573af2 | 2013-07-27 12:57:08 -0700 | [diff] [blame] | 146 | { |
Alexander Afanasyev | be55cf6 | 2014-12-20 17:51:09 -0800 | [diff] [blame] | 147 | TcpFaceMap::iterator i = m_tcpFaceMap.find(address); |
| 148 | if (i != m_tcpFaceMap.end()) |
Alexander Afanasyev | d573af2 | 2013-07-27 12:57:08 -0700 | [diff] [blame] | 149 | return i->second; |
| 150 | else |
| 151 | return 0; |
| 152 | } |
| 153 | |
| 154 | void |
Alexander Afanasyev | be55cf6 | 2014-12-20 17:51:09 -0800 | [diff] [blame] | 155 | IpFaceStack::DestroyTcpFace(Ptr<TcpFace> face) |
Alexander Afanasyev | d573af2 | 2013-07-27 12:57:08 -0700 | [diff] [blame] | 156 | { |
Alexander Afanasyev | be55cf6 | 2014-12-20 17:51:09 -0800 | [diff] [blame] | 157 | m_tcpFaceMap.erase(face->GetAddress()); |
Alexander Afanasyev | d573af2 | 2013-07-27 12:57:08 -0700 | [diff] [blame] | 158 | } |
| 159 | |
| 160 | Ptr<UdpFace> |
Alexander Afanasyev | be55cf6 | 2014-12-20 17:51:09 -0800 | [diff] [blame] | 161 | IpFaceStack::GetUdpFaceByAddress(const Ipv4Address& address) |
Alexander Afanasyev | d573af2 | 2013-07-27 12:57:08 -0700 | [diff] [blame] | 162 | { |
Alexander Afanasyev | be55cf6 | 2014-12-20 17:51:09 -0800 | [diff] [blame] | 163 | UdpFaceMap::iterator i = m_udpFaceMap.find(address); |
| 164 | if (i != m_udpFaceMap.end()) |
Alexander Afanasyev | d573af2 | 2013-07-27 12:57:08 -0700 | [diff] [blame] | 165 | return i->second; |
| 166 | else |
| 167 | return 0; |
| 168 | } |
| 169 | |
| 170 | Ptr<TcpFace> |
Alexander Afanasyev | be55cf6 | 2014-12-20 17:51:09 -0800 | [diff] [blame] | 171 | IpFaceStack::CreateOrGetTcpFace(Ipv4Address address, Callback<void, Ptr<Face>> onCreate) |
Alexander Afanasyev | d573af2 | 2013-07-27 12:57:08 -0700 | [diff] [blame] | 172 | { |
Alexander Afanasyev | be55cf6 | 2014-12-20 17:51:09 -0800 | [diff] [blame] | 173 | NS_LOG_FUNCTION(address); |
Alexander Afanasyev | d573af2 | 2013-07-27 12:57:08 -0700 | [diff] [blame] | 174 | |
Alexander Afanasyev | be55cf6 | 2014-12-20 17:51:09 -0800 | [diff] [blame] | 175 | TcpFaceMap::iterator i = m_tcpFaceMap.find(address); |
| 176 | if (i != m_tcpFaceMap.end()) |
Alexander Afanasyev | d573af2 | 2013-07-27 12:57:08 -0700 | [diff] [blame] | 177 | return i->second; |
| 178 | |
Alexander Afanasyev | be55cf6 | 2014-12-20 17:51:09 -0800 | [diff] [blame] | 179 | Ptr<Socket> socket = Socket::CreateSocket(m_node, TcpSocketFactory::GetTypeId()); |
| 180 | Ptr<TcpFace> face = CreateObject<TcpFace>(m_node, socket, address); |
Alexander Afanasyev | d573af2 | 2013-07-27 12:57:08 -0700 | [diff] [blame] | 181 | |
Alexander Afanasyev | be55cf6 | 2014-12-20 17:51:09 -0800 | [diff] [blame] | 182 | face->SetCreateCallback(onCreate); |
Alexander Afanasyev | d573af2 | 2013-07-27 12:57:08 -0700 | [diff] [blame] | 183 | |
Alexander Afanasyev | be55cf6 | 2014-12-20 17:51:09 -0800 | [diff] [blame] | 184 | socket->SetConnectCallback(MakeCallback(&TcpFace::OnConnect, face), |
| 185 | MakeNullCallback<void, Ptr<Socket>>()); |
| 186 | socket->Connect(InetSocketAddress(address, L3Protocol::IP_STACK_PORT)); |
Alexander Afanasyev | d573af2 | 2013-07-27 12:57:08 -0700 | [diff] [blame] | 187 | |
Alexander Afanasyev | be55cf6 | 2014-12-20 17:51:09 -0800 | [diff] [blame] | 188 | m_tcpFaceMap.insert(std::make_pair(address, face)); |
Alexander Afanasyev | d573af2 | 2013-07-27 12:57:08 -0700 | [diff] [blame] | 189 | |
| 190 | return face; |
| 191 | } |
| 192 | |
| 193 | Ptr<UdpFace> |
Alexander Afanasyev | be55cf6 | 2014-12-20 17:51:09 -0800 | [diff] [blame] | 194 | IpFaceStack::CreateOrGetUdpFace(Ipv4Address address) |
Alexander Afanasyev | d573af2 | 2013-07-27 12:57:08 -0700 | [diff] [blame] | 195 | { |
Alexander Afanasyev | be55cf6 | 2014-12-20 17:51:09 -0800 | [diff] [blame] | 196 | NS_LOG_FUNCTION(address); |
Alexander Afanasyev | d573af2 | 2013-07-27 12:57:08 -0700 | [diff] [blame] | 197 | |
Alexander Afanasyev | be55cf6 | 2014-12-20 17:51:09 -0800 | [diff] [blame] | 198 | UdpFaceMap::iterator i = m_udpFaceMap.find(address); |
| 199 | if (i != m_udpFaceMap.end()) |
Alexander Afanasyev | d573af2 | 2013-07-27 12:57:08 -0700 | [diff] [blame] | 200 | return i->second; |
| 201 | |
Alexander Afanasyev | be55cf6 | 2014-12-20 17:51:09 -0800 | [diff] [blame] | 202 | Ptr<Socket> socket = Socket::CreateSocket(m_node, UdpSocketFactory::GetTypeId()); |
| 203 | socket->Bind(InetSocketAddress(Ipv4Address::GetAny(), |
| 204 | L3Protocol::IP_STACK_PORT)); // not sure if it going to work... |
Alexander Afanasyev | d573af2 | 2013-07-27 12:57:08 -0700 | [diff] [blame] | 205 | // socket->Bind (); |
Alexander Afanasyev | be55cf6 | 2014-12-20 17:51:09 -0800 | [diff] [blame] | 206 | socket->Connect(InetSocketAddress(address, L3Protocol::IP_STACK_PORT)); |
Alexander Afanasyev | d573af2 | 2013-07-27 12:57:08 -0700 | [diff] [blame] | 207 | |
Alexander Afanasyev | be55cf6 | 2014-12-20 17:51:09 -0800 | [diff] [blame] | 208 | Ptr<UdpFace> face = CreateObject<UdpFace>(m_node, socket, address); |
| 209 | Ptr<L3Protocol> ndn = m_node->GetObject<L3Protocol>(); |
Alexander Afanasyev | d573af2 | 2013-07-27 12:57:08 -0700 | [diff] [blame] | 210 | |
Alexander Afanasyev | be55cf6 | 2014-12-20 17:51:09 -0800 | [diff] [blame] | 211 | ndn->AddFace(face); |
| 212 | face->SetUp(true); |
Alexander Afanasyev | d573af2 | 2013-07-27 12:57:08 -0700 | [diff] [blame] | 213 | |
Alexander Afanasyev | be55cf6 | 2014-12-20 17:51:09 -0800 | [diff] [blame] | 214 | m_udpFaceMap.insert(std::make_pair(address, face)); |
Alexander Afanasyev | d573af2 | 2013-07-27 12:57:08 -0700 | [diff] [blame] | 215 | return face; |
| 216 | } |
| 217 | |
Alexander Afanasyev | f4e2452 | 2013-06-24 14:11:57 -0700 | [diff] [blame] | 218 | } // namespace ndn |
| 219 | } // namespace ns3 |