A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
socket.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2006 Georgia Tech Research Corporation
4  * 2007 INRIA
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  * Authors: George F. Riley<riley@ece.gatech.edu>
20  * Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
21  */
22 
23 #include "ns3/log.h"
24 #include "ns3/packet.h"
25 #include "node.h"
26 #include "socket.h"
27 #include "socket-factory.h"
28 #include <limits>
29 
30 NS_LOG_COMPONENT_DEFINE ("Socket");
31 
32 namespace ns3 {
33 
35 
36 TypeId
38 {
39  static TypeId tid = TypeId ("ns3::Socket")
40  .SetParent<Object> ();
41  return tid;
42 }
43 
45 {
46  m_boundnetdevice = 0;
47  m_recvPktInfo = false;
49 }
50 
52 {
54 }
55 
58 {
59  Ptr<Socket> s;
60  NS_ASSERT (node != 0);
61  Ptr<SocketFactory> socketFactory = node->GetObject<SocketFactory> (tid);
62  NS_ASSERT (socketFactory != 0);
63  s = socketFactory->CreateSocket ();
64  NS_ASSERT (s != 0);
65  return s;
66 }
67 
68 void
70  Callback<void, Ptr<Socket> > connectionSucceeded,
71  Callback<void, Ptr<Socket> > connectionFailed)
72 {
74  m_connectionSucceeded = connectionSucceeded;
75  m_connectionFailed = connectionFailed;
76 }
77 
78 void
80  Callback<void, Ptr<Socket> > normalClose,
81  Callback<void, Ptr<Socket> > errorClose)
82 {
84  m_normalClose = normalClose;
85  m_errorClose = errorClose;
86 }
87 
88 void
90  Callback<bool, Ptr<Socket>, const Address &> connectionRequest,
91  Callback<void, Ptr<Socket>, const Address&> newConnectionCreated)
92 {
94  m_connectionRequest = connectionRequest;
95  m_newConnectionCreated = newConnectionCreated;
96 }
97 
98 void
100 {
102  m_dataSent = dataSent;
103 }
104 
105 void
107 {
109  m_sendCb = sendCb;
110 }
111 
112 void
114 {
116  m_receivedData = receivedData;
117 }
118 
119 int
121 {
123  return Send (p, 0);
124 }
125 
126 int
127 Socket::Send (const uint8_t* buf, uint32_t size, uint32_t flags)
128 {
130  Ptr<Packet> p;
131  if (buf)
132  {
133  p = Create<Packet> (buf, size);
134  }
135  else
136  {
137  p = Create<Packet> (size);
138  }
139  return Send (p, flags);
140 }
141 
142 int
143 Socket::SendTo (const uint8_t* buf, uint32_t size, uint32_t flags,
144  const Address &toAddress)
145 {
147  Ptr<Packet> p;
148  if(buf)
149  {
150  p = Create<Packet> (buf, size);
151  }
152  else
153  {
154  p = Create<Packet> (size);
155  }
156  return SendTo (p, flags, toAddress);
157 }
158 
161 {
163  return Recv (std::numeric_limits<uint32_t>::max (), 0);
164 }
165 
166 int
167 Socket::Recv (uint8_t* buf, uint32_t size, uint32_t flags)
168 {
170  Ptr<Packet> p = Recv (size, flags); // read up to "size" bytes
171  if (p == 0)
172  {
173  return 0;
174  }
175  p->CopyData (buf, p->GetSize ());
176  return p->GetSize ();
177 }
178 
180 Socket::RecvFrom (Address &fromAddress)
181 {
183  return RecvFrom (std::numeric_limits<uint32_t>::max (), 0, fromAddress);
184 }
185 
186 int
187 Socket::RecvFrom (uint8_t* buf, uint32_t size, uint32_t flags,
188  Address &fromAddress)
189 {
191  Ptr<Packet> p = RecvFrom (size, flags, fromAddress);
192  if (p == 0)
193  {
194  return 0;
195  }
196  p->CopyData (buf, p->GetSize ());
197  return p->GetSize ();
198 }
199 
200 
201 void
203 {
206  {
207  m_connectionSucceeded (this);
208  }
209 }
210 
211 void
213 {
215  if (!m_connectionFailed.IsNull ())
216  {
217  m_connectionFailed (this);
218  }
219 }
220 
221 void
223 {
225  if (!m_normalClose.IsNull ())
226  {
227  m_normalClose (this);
228  }
229 }
230 
231 void
233 {
235  if (!m_errorClose.IsNull ())
236  {
237  m_errorClose (this);
238  }
239 }
240 
241 bool
243 {
245  if (!m_connectionRequest.IsNull ())
246  {
247  return m_connectionRequest (this, from);
248  }
249  else
250  {
251  // accept all incoming connections by default.
252  // this way people writing code don't have to do anything
253  // special like register a callback that returns true
254  // just to get incoming connections
255  return true;
256  }
257 }
258 
259 void
261 {
264  {
265  m_newConnectionCreated (socket, from);
266  }
267 }
268 
269 void
270 Socket::NotifyDataSent (uint32_t size)
271 {
273  if (!m_dataSent.IsNull ())
274  {
275  m_dataSent (this, size);
276  }
277 }
278 
279 void
280 Socket::NotifySend (uint32_t spaceAvailable)
281 {
283  if (!m_sendCb.IsNull ())
284  {
285  m_sendCb (this, spaceAvailable);
286  }
287 }
288 
289 void
291 {
293  if (!m_receivedData.IsNull ())
294  {
295  m_receivedData (this);
296  }
297 }
298 
299 void
301 {
302 
303  m_connectionSucceeded = MakeNullCallback<void,Ptr<Socket> > ();
304  m_connectionFailed = MakeNullCallback<void,Ptr<Socket> > ();
305  m_normalClose = MakeNullCallback<void,Ptr<Socket> > ();
306  m_errorClose = MakeNullCallback<void,Ptr<Socket> > ();
307  m_connectionRequest = MakeNullCallback<bool,Ptr<Socket>, const Address &> ();
308  m_newConnectionCreated = MakeNullCallback<void,Ptr<Socket>, const Address &> ();
309  m_dataSent = MakeNullCallback<void,Ptr<Socket>, uint32_t> ();
310  m_sendCb = MakeNullCallback<void,Ptr<Socket>, uint32_t> ();
311  m_receivedData = MakeNullCallback<void,Ptr<Socket> > ();
312 }
313 
314 void
316 {
317  if (netdevice != 0)
318  {
319  bool found = false;
320  for (uint32_t i = 0; i < GetNode ()->GetNDevices (); i++)
321  {
322  if (GetNode ()->GetDevice (i) == netdevice)
323  {
324  found = true;
325  break;
326  }
327  }
328  NS_ASSERT_MSG (found, "Socket cannot be bound to a NetDevice not existing on the Node");
329  }
330  m_boundnetdevice = netdevice;
331  return;
332 }
333 
336 {
337  return m_boundnetdevice;
338 }
339 
340 void
342 {
344  m_recvPktInfo = flag;
345 }
346 
348 {
350  return m_recvPktInfo;
351 }
352 
353 /***************************************************************
354  * Socket Tags
355  ***************************************************************/
356 
358 {
359 }
360 
361 void
363 {
364  m_address = addr;
365 }
366 
367 Address
369 {
370  return m_address;
371 }
372 
374 
375 TypeId
377 {
378  static TypeId tid = TypeId ("ns3::SocketAddressTag")
379  .SetParent<Tag> ()
380  .AddConstructor<SocketAddressTag> ()
381  ;
382  return tid;
383 }
384 TypeId
386 {
387  return GetTypeId ();
388 }
389 uint32_t
391 {
392  return m_address.GetSerializedSize ();
393 }
394 void
396 {
397  m_address.Serialize (i);
398 }
399 void
401 {
403 }
404 void
405 SocketAddressTag::Print (std::ostream &os) const
406 {
407  os << "address=" << m_address;
408 }
409 
411 {
412 }
413 
414 void
416 {
417  m_ttl = ttl;
418 }
419 
420 uint8_t
422 {
423  return m_ttl;
424 }
425 
427 
428 TypeId
430 {
431  static TypeId tid = TypeId ("ns3::SocketIpTtlTag")
432  .SetParent<Tag> ()
433  .AddConstructor<SocketIpTtlTag> ()
434  ;
435  return tid;
436 }
437 TypeId
439 {
440  return GetTypeId ();
441 }
442 
443 uint32_t
445 {
446  return 1;
447 }
448 void
450 {
451  i.WriteU8 (m_ttl);
452 }
453 void
455 {
456  m_ttl = i.ReadU8 ();
457 }
458 void
459 SocketIpTtlTag::Print (std::ostream &os) const
460 {
461  os << "Ttl=" << (uint32_t) m_ttl;
462 }
463 
464 
466 {
467 }
468 void
470 {
471  m_dontFragment = true;
472 }
473 void
475 {
476  m_dontFragment = false;
477 }
478 bool
480 {
481  return m_dontFragment;
482 }
483 
485 
486 TypeId
488 {
489  static TypeId tid = TypeId ("ns3::SocketSetDontFragmentTag")
490  .SetParent<Tag> ()
491  .AddConstructor<SocketSetDontFragmentTag> ()
492  ;
493  return tid;
494 }
495 TypeId
497 {
498  return GetTypeId ();
499 }
500 uint32_t
502 {
503  return 1;
504 }
505 void
507 {
508  i.WriteU8 (m_dontFragment ? 1 : 0);
509 }
510 void
512 {
513  m_dontFragment = (i.ReadU8 () == 1) ? true : false;
514 }
515 void
516 SocketSetDontFragmentTag::Print (std::ostream &os) const
517 {
518  os << (m_dontFragment ? "true" : "false");
519 }
520 
521 } // namespace ns3