1/**********
2This library is free software; you can redistribute it and/or modify it under
3the terms of the GNU Lesser General Public License as published by the
4Free Software Foundation; either version 3 of the License, or (at your
5option) any later version. (See <http://www.gnu.org/copyleft/lesser.html>.)
6
7This library is distributed in the hope that it will be useful, but WITHOUT
8ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
9FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
10more details.
11
12You should have received a copy of the GNU Lesser General Public License
13along with this library; if not, write to the Free Software Foundation, Inc.,
1451 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
15**********/
16// "mTunnel" multicast access service
17// Copyright (c) 1996-2020 Live Networks, Inc. All rights reserved.
18// Network Interfaces
19// Implementation
20
21#include "NetInterface.hh"
22#include "GroupsockHelper.hh"
23
24#ifndef NO_SSTREAM
25#include <sstream>
26#endif
27#include <stdio.h>
28
29////////// NetInterface //////////
30
31UsageEnvironment* NetInterface::DefaultUsageEnvironment = NULL;
32
33NetInterface::NetInterface() {
34}
35
36NetInterface::~NetInterface() {
37}
38
39
40////////// NetInterface //////////
41
42DirectedNetInterface::DirectedNetInterface() {
43}
44
45DirectedNetInterface::~DirectedNetInterface() {
46}
47
48
49////////// DirectedNetInterfaceSet //////////
50
51DirectedNetInterfaceSet::DirectedNetInterfaceSet()
52 : fTable(HashTable::create(ONE_WORD_HASH_KEYS)) {
53}
54
55DirectedNetInterfaceSet::~DirectedNetInterfaceSet() {
56 delete fTable;
57}
58
59DirectedNetInterface*
60DirectedNetInterfaceSet::Add(DirectedNetInterface const* interf) {
61 return (DirectedNetInterface*) fTable->Add((char*)interf, (void*)interf);
62}
63
64Boolean
65DirectedNetInterfaceSet::Remove(DirectedNetInterface const* interf) {
66 return fTable->Remove((char*)interf);
67}
68
69DirectedNetInterfaceSet::Iterator::
70Iterator(DirectedNetInterfaceSet& interfaces)
71 : fIter(HashTable::Iterator::create(*(interfaces.fTable))) {
72}
73
74DirectedNetInterfaceSet::Iterator::~Iterator() {
75 delete fIter;
76}
77
78DirectedNetInterface* DirectedNetInterfaceSet::Iterator::next() {
79 char const* key; // dummy
80 return (DirectedNetInterface*) fIter->next(key);
81};
82
83
84////////// Socket //////////
85
86int Socket::DebugLevel = 1; // default value
87
88Socket::Socket(UsageEnvironment& env, Port port)
89 : fEnv(DefaultUsageEnvironment != NULL ? *DefaultUsageEnvironment : env), fPort(port) {
90 fSocketNum = setupDatagramSocket(fEnv, port);
91}
92
93void Socket::reset() {
94 if (fSocketNum >= 0) closeSocket(fSocketNum);
95 fSocketNum = -1;
96}
97
98Socket::~Socket() {
99 reset();
100}
101
102Boolean Socket::changePort(Port newPort) {
103 int oldSocketNum = fSocketNum;
104 unsigned oldReceiveBufferSize = getReceiveBufferSize(fEnv, fSocketNum);
105 unsigned oldSendBufferSize = getSendBufferSize(fEnv, fSocketNum);
106 closeSocket(fSocketNum);
107
108 fSocketNum = setupDatagramSocket(fEnv, newPort);
109 if (fSocketNum < 0) {
110 fEnv.taskScheduler().turnOffBackgroundReadHandling(oldSocketNum);
111 return False;
112 }
113
114 setReceiveBufferTo(fEnv, fSocketNum, oldReceiveBufferSize);
115 setSendBufferTo(fEnv, fSocketNum, oldSendBufferSize);
116 if (fSocketNum != oldSocketNum) { // the socket number has changed, so move any event handling for it:
117 fEnv.taskScheduler().moveSocketHandling(oldSocketNum, fSocketNum);
118 }
119 return True;
120}
121
122UsageEnvironment& operator<<(UsageEnvironment& s, const Socket& sock) {
123 return s << timestampString() << " Socket(" << sock.socketNum() << ")";
124}
125
126////////// SocketLookupTable //////////
127
128SocketLookupTable::SocketLookupTable()
129 : fTable(HashTable::create(ONE_WORD_HASH_KEYS)) {
130}
131
132SocketLookupTable::~SocketLookupTable() {
133 delete fTable;
134}
135
136Socket* SocketLookupTable::Fetch(UsageEnvironment& env, Port port,
137 Boolean& isNew) {
138 isNew = False;
139 Socket* sock;
140 do {
141 sock = (Socket*) fTable->Lookup((char*)(long)(port.num()));
142 if (sock == NULL) { // we need to create one:
143 sock = CreateNew(env, port);
144 if (sock == NULL || sock->socketNum() < 0) break;
145
146 fTable->Add((char*)(long)(port.num()), (void*)sock);
147 isNew = True;
148 }
149
150 return sock;
151 } while (0);
152
153 delete sock;
154 return NULL;
155}
156
157Boolean SocketLookupTable::Remove(Socket const* sock) {
158 return fTable->Remove( (char*)(long)(sock->port().num()) );
159}
160
161////////// NetInterfaceTrafficStats //////////
162
163NetInterfaceTrafficStats::NetInterfaceTrafficStats() {
164 fTotNumPackets = fTotNumBytes = 0.0;
165}
166
167void NetInterfaceTrafficStats::countPacket(unsigned packetSize) {
168 fTotNumPackets += 1.0;
169 fTotNumBytes += packetSize;
170}
171
172Boolean NetInterfaceTrafficStats::haveSeenTraffic() const {
173 return fTotNumPackets != 0.0;
174}
175