A Discrete-Event Network Simulator
API
sensornode.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 
3 /*
4 * Copyright (c) 2020 DLTLT
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation;
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 * Corresponding author: Niki Hrovatin <niki.hrovatin@famnit.upr.si>
20 */
21 
22 #include "sensornode.h"
23 
24 namespace ns3 {
25 
26 //Zagotovi, da se registrira TypeId
27 NS_OBJECT_ENSURE_REGISTERED (SensorNode);
28 
29 NS_LOG_COMPONENT_DEFINE ("sensornode");
30 
31 TypeId
33 {
34  static TypeId tid = TypeId ("ns3::SensorNode")
35  .SetParent<Wsn_node> ()
36  .AddConstructor<SensorNode> ()
37  .AddAttribute ("SinkNodeAddress", "Address to send packets.",
38  Ipv4AddressValue (Ipv4Address::GetAny ()),
39  MakeIpv4AddressAccessor (&SensorNode::m_sinkAddress),
40  MakeIpv4AddressChecker ());
41 
42  return tid;
43 }
44 
46 {
47 }
48 
50 {
51  m_socket = 0;
52 }
53 
54 //Send the public key to the source
55 
56 void
58 {
59  std::string pk = m_onionManager.GetPKtoString ();
60 
61  //construct a new packet /w publickey type of sensor
62  protomessage::ProtoPacket handshake_message;
63  handshake_message.mutable_h_shake ()->set_publickey (pk); //publickey
64  SerializationWrapper sw (handshake_message);
65  Ptr<Packet> p = Create<Packet> ();
66  p->AddHeader (sw);
67 
68  //send to the sink node
69  InetSocketAddress remote (m_sinkAddress, m_port);
70  Wsn_node::SendSegment (remote, p, false);
71 
72  //Simulator::Schedule (Seconds (5), &Wsn_node::DisableNode, this);
73 
74  //Simulator::Schedule (Seconds (60), &Wsn_node::ActivateNode, this);
75 }
76 
77 //callback, when the onion is received
78 void
79 SensorNode::ReceivePacket (Ptr<Socket> socket)
80 {
81 
82  Ptr<Packet> p = Wsn_node::RecvSegment (socket);
83 
84  if (p != NULL)
85  {
86  NotifyRx (p);
88  //get the onion message
90  p->RemoveHeader (sw);
91  sw.GetData (&onion);
92 
93  //get the onion ID
94  o_sequenceNum = onion.mutable_o_head ()->onionid ();
95 
96  if (o_sequenceNum == m_onionValidator->GetOnionSeq ())
97  { //message IDs are equal
98 
99  //Call that the onion was received
100  m_outputManager->OnionRoutingRecv (Simulator::Now ());
102 
103  //Process onion head and get next hop IP address
104  uint32_t ip = ProcessOnionHead (onion.mutable_o_head ());
105 
106  //ProcessOnionHead();
107  ProcessOnionBody (onion.mutable_o_body ());
108 
109  //create the packet
110  Ptr<Packet> np = Create<Packet> ();
111  sw.SetData (onion);
112  np = Create<Packet> ();
113 
114  np->AddHeader (sw);
115 
116  //send further the message
117  InetSocketAddress remote (Ipv4Address (ip), m_port);
118  NotifyTx (p);
119  Wsn_node::SendSegment (remote, np, true);
120 
122  m_outputManager->OnionRoutingSend (
123  m_address, Ipv4Address (ip), np->GetSize (), onion.mutable_o_head ()->ByteSizeLong (),
124  onion.mutable_o_body ()->ByteSizeLong (), Simulator::Now ());
125  }
126  else
127  { //the onion should be deleted
128  NS_LOG_INFO ("Ghost onion received, deleted with onion id: "
129  << o_sequenceNum << ", at ip: " << m_address
130  << ", at time: " << std::to_string (Simulator::Now ().GetSeconds ()));
131  }
132  }
133 }
134 
135 uint32_t
137 {
138  std::string onion = onionHead->onion_message ();
139 
140  //get length in bytes of the onion
141  int outer_layer_len = onion.length ();
142 
143  //get previous padding
144  if (onionHead->has_padding ())
145  {
146  outer_layer_len += onionHead->padding ().length ();
147  }
148 
149  //decrypt the onion
150  unsigned char *serialized_onion = m_onionManager.StringToUchar (onion);
151  orLayer *onionLayer = m_onionManager.PeelOnion (serialized_onion, onion.length (),
153 
154  //convert ip from the onion to uint32
155  uint32_t ip = DeserializeIpv4ToInt (onionLayer->nextHopIP);
156  //convert onion to string for serialization
157  onion = m_onionManager.UcharToString (onionLayer->innerLayer, onionLayer->innerLayerLen);
158 
159  //mount the onion head
160  onionHead->set_onion_message (onion);
161 
162  //add padding if set
163  if (onionHead->has_padding ())
164  {
165  std::string padding (outer_layer_len - onion.length (), '0');
166  onionHead->set_padding (padding);
167  }
168 
169  //release memory
170  delete[] onionLayer->nextHopIP;
171  delete onionLayer;
172  delete[] serialized_onion;
173 
174  return ip;
175 }
176 
177 void
179 {
180  if (onionBody->has_aggregatedvalue ())
181  {
182  //get the content - payload
183  int value = onionBody->aggregatedvalue ();
184  // Compute the aggregate
185  value = value + m_sensorValue;
186  //set the new value
187  onionBody->set_aggregatedvalue (value);
188  }
189 }
190 
191 uint32_t
193 {
194  uint32_t ip = 0;
195  ip += buff[0];
196  ip = ip << 8;
197  ip += buff[1];
198  ip = ip << 8;
199  ip += buff[2];
200  ip = ip << 8;
201  ip += buff[3];
202  return ip;
203 }
204 
205 //callback, at a new connection
206 void
207 SensorNode::Accept (Ptr<Socket> socket, const ns3::Address &from)
208 {
209  socket->SetRecvCallback (MakeCallback (&SensorNode::ReceivePacket, this));
210 }
211 
212 // executes at start
213 void
215 {
216  //basic configuration
218 
219  //Generate encryption keys
221 
222  uint32_t delay = Wsn_node::getNodeDelay (m_address);
223 
224  Simulator::Schedule (MilliSeconds (delay), &SensorNode::Handshake, this);
225 
226  //get the new connection
227  m_socket->SetAcceptCallback (MakeNullCallback<bool, Ptr<Socket>, const Address &> (),
228  MakeCallback (&SensorNode::Accept, this));
229 }
230 
231 void
233 {
234  if (m_socket)
235  {
236  m_socket->Close ();
237  }
238 }
239 
240 } // namespace ns3
ns3::Wsn_node::m_socket
Ptr< Socket > m_socket
listening socket
Definition: wsn_node.h:228
protomessage::ProtoPacket::mutable_h_shake
::protomessage::ProtoPacket_Handshake * mutable_h_shake()
Definition: proto-packet.pb.h:1216
protomessage::ProtoPacket_OnionHead::has_padding
bool has_padding() const
Definition: proto-packet.pb.h:909
ns3::Wsn_node::RecvSegment
Ptr< Packet > RecvSegment(Ptr< Socket > socket)
method for receiving a segment calls ns3::Wsn_node::RecvSeg()
Definition: wsn_node.cc:249
ns3::OnionManager::GetPKtoString
std::string GetPKtoString()
accessor
Definition: onionmanager.cc:103
ns3::Wsn_node::o_sequenceNum
int o_sequenceNum
sequence number of the onion, should be same as onion_id
Definition: wsn_node.h:241
ns3
Definition: sensornode-helper.cc:26
ns3::Wsn_node::SendSegment
void SendSegment(InetSocketAddress remote, Ptr< Packet > packet, bool b_onion)
Send a packet through a TCP connection to the remote address.
Definition: wsn_node.cc:217
ns3::SerializationWrapper::SetData
void SetData(protomessage::ProtoPacket message)
Setter of the data in the protocol header.
Definition: serializationwrapper.cc:58
protomessage::ProtoPacket::mutable_o_body
::protomessage::ProtoPacket_OnionBody * mutable_o_body()
Definition: proto-packet.pb.h:1396
ns3::Wsn_node::getNodeDelay
uint32_t getNodeDelay(Ipv4Address node_address)
compute when the node should start the handshake process from the node ip address Used to not generat...
Definition: wsn_node.cc:198
ns3::orLayer::nextHopIP
uint8_t * nextHopIP
ip address given in the serialized form
Definition: onion-routing.h:23
protomessage::ProtoPacket_OnionBody::ByteSizeLong
size_t ByteSizeLong() const final
Definition: proto-packet.pb.cc:623
protomessage::ProtoPacket_OnionHead::onionid
int32_t onionid() const
Definition: proto-packet.pb.h:822
protomessage::ProtoPacket_OnionHead::onion_message
const std::string & onion_message() const
Definition: proto-packet.pb.h:847
ns3::Wsn_node::m_onionValidator
Ptr< OnionValidator > m_onionValidator
Pointer to the ns3::OnionValidator.
Definition: wsn_node.h:226
ns3::SensorNode::SensorNode
SensorNode()
Default constructor.
Definition: sensornode.cc:45
ns3::OnionManager::UcharToString
std::string UcharToString(unsigned char *seq, int len)
Convert an array of unsigned chars to a std::string.
Definition: onionmanager.cc:147
ns3::SensorNode::m_sensorValue
uint32_t m_sensorValue
dummy reading of a sensor equipped on the node
Definition: sensornode.h:162
ns3::SensorNode::ReceivePacket
void ReceivePacket(Ptr< Socket > socket)
Executed when a new onion is received.
Definition: sensornode.cc:79
ns3::OnionRouting::PeelOnion
orLayer * PeelOnion(uint8_t *onion, uint16_t onionLen, uint8_t *pk, uint8_t *sk)
Definition: onion-routing.cc:158
ns3::OnionManager::StringToUchar
unsigned char * StringToUchar(std::string in)
Convert a string to an array of unsigned chars.
Definition: onionmanager.cc:138
ns3::Wsn_node::m_address
Ipv4Address m_address
ns3::Ipv4Address of this node
Definition: wsn_node.h:227
sensornode.h
ns3::SensorNode::StartApplication
virtual void StartApplication(void)
1.Start the application run ns3::Wsn_node::Configure() 2.Generate new encryption keys 3....
Definition: sensornode.cc:214
ns3::SensorNode::ProcessOnionHead
uint32_t ProcessOnionHead(protomessage::ProtoPacket_OnionHead *onionHead)
Decrypt the outer layer of the onion head, obtain the information of the next IP address,...
Definition: sensornode.cc:136
ns3::SensorNode::StopApplication
virtual void StopApplication(void)
Stop the application.
Definition: sensornode.cc:232
protomessage::ProtoPacket::mutable_o_head
::protomessage::ProtoPacket_OnionHead * mutable_o_head()
Definition: proto-packet.pb.h:1306
ns3::orLayer
structure holding details resulting from layer decryption of an onion message
Definition: onion-routing.h:22
protomessage::ProtoPacket_OnionHead::set_onion_message
void set_onion_message(ArgT0 &&arg0, ArgT... args)
ns3::OnionManager::GetPK
unsigned char * GetPK(void)
accessor
Definition: onionmanager.cc:88
ns3::orLayer::innerLayer
uint8_t * innerLayer
inner content of the onion message without the next hop address
Definition: onion-routing.h:24
ns3::SensorNode::GetTypeId
static TypeId GetTypeId(void)
Register this type.
Definition: sensornode.cc:32
protomessage::ProtoPacket_OnionHead::padding
const std::string & padding() const
Definition: proto-packet.pb.h:916
ns3::Wsn_node::NotifyRx
void NotifyRx(Ptr< const Packet > packet)
Call to signal the receipt of a Packet at the application layer.
Definition: wsn_node.cc:82
ns3::Wsn_node::m_onionManager
OnionManager m_onionManager
The ns3::OnionManager object.
Definition: wsn_node.h:230
protomessage::ProtoPacket_Handshake::set_publickey
void set_publickey(ArgT0 &&arg0, ArgT... args)
protomessage::ProtoPacket_OnionBody::aggregatedvalue
int32_t aggregatedvalue() const
Definition: proto-packet.pb.h:992
ns3::SerializationWrapper
Class for the serialization-deserialization of the messagess to send in packets.
Definition: serializationwrapper.h:54
ns3::Wsn_node::m_outputManager
Ptr< OutputManager > m_outputManager
Pointer to the ns3::OutputManager.
Definition: wsn_node.h:225
protomessage::ProtoPacket_OnionBody
Definition: proto-packet.pb.h:271
ns3::Wsn_node::m_port
uint16_t m_port
port of the application
Definition: wsn_node.h:224
protomessage::ProtoPacket_OnionHead
Definition: proto-packet.pb.h:80
ns3::Wsn_node
The wsn node base class that manages the sending and receiving of packets and basic configuration of ...
Definition: wsn_node.h:61
ns3::SensorNode::Handshake
void Handshake(void)
Construct a new protobuf object containing the node publickey and send it to the sink node.
Definition: sensornode.cc:57
ns3::OnionManager::GenerateNewKeyPair
void GenerateNewKeyPair(void)
Generate a new public/private keypair using the libsodium library.
Definition: onionmanager.cc:81
ns3::orLayer::innerLayerLen
uint16_t innerLayerLen
length of the inner content of the onion message
Definition: onion-routing.h:25
ns3::SensorNode::~SensorNode
virtual ~SensorNode()
Default destructor.
Definition: sensornode.cc:49
ns3::OnionManager::GetSK
unsigned char * GetSK(void)
accessor
Definition: onionmanager.cc:96
ns3::Wsn_node::NotifyTx
void NotifyTx(Ptr< const Packet > packet)
Call to signal the transmission of a Packet at the application layer.
Definition: wsn_node.cc:76
protomessage::ProtoPacket
Definition: proto-packet.pb.h:598
ns3::SensorNode::m_sinkAddress
Ipv4Address m_sinkAddress
address of the sink node
Definition: sensornode.h:160
ns3::Wsn_node::Configure
void Configure(void)
1.
Definition: wsn_node.cc:102
protomessage::ProtoPacket_OnionBody::set_aggregatedvalue
void set_aggregatedvalue(int32_t value)
Definition: proto-packet.pb.h:1000
protomessage::ProtoPacket_OnionHead::set_padding
void set_padding(ArgT0 &&arg0, ArgT... args)
protomessage::ProtoPacket_OnionBody::has_aggregatedvalue
bool has_aggregatedvalue() const
Definition: proto-packet.pb.h:982
ns3::Wsn_node::OnionReceived
void OnionReceived(void)
Signal to the ns3::OnionValidator that the onion was corrctly received.
Definition: wsn_node.cc:331
ns3::SensorNode::Accept
void Accept(Ptr< Socket > socket, const ns3::Address &from)
Accept new TCP connections.
Definition: sensornode.cc:207
ns3::SensorNode::ProcessOnionBody
void ProcessOnionBody(protomessage::ProtoPacket_OnionBody *onionbody)
If the onion body contains the aggregated value, then aggregate the sensor (dummy) value to the value...
Definition: sensornode.cc:178
ns3::SerializationWrapper::GetData
void GetData(protomessage::ProtoPacket *message)
Getter of the data in the protocol header.
Definition: serializationwrapper.cc:78
protomessage::ProtoPacket_OnionHead::ByteSizeLong
size_t ByteSizeLong() const final
Definition: proto-packet.pb.cc:361
ns3::SensorNode::DeserializeIpv4ToInt
uint32_t DeserializeIpv4ToInt(uint8_t *buff)
Convert an IPV4 address given as a buffer.
Definition: sensornode.cc:192