1 | /********** |
2 | This library is free software; you can redistribute it and/or modify it under |
3 | the terms of the GNU Lesser General Public License as published by the |
4 | Free Software Foundation; either version 3 of the License, or (at your |
5 | option) any later version. (See <http://www.gnu.org/copyleft/lesser.html>.) |
6 | |
7 | This library is distributed in the hope that it will be useful, but WITHOUT |
8 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
9 | FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for |
10 | more details. |
11 | |
12 | You should have received a copy of the GNU Lesser General Public License |
13 | along with this library; if not, write to the Free Software Foundation, Inc., |
14 | 51 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 | |
31 | UsageEnvironment* NetInterface::DefaultUsageEnvironment = NULL; |
32 | |
33 | NetInterface::NetInterface() { |
34 | } |
35 | |
36 | NetInterface::~NetInterface() { |
37 | } |
38 | |
39 | |
40 | ////////// NetInterface ////////// |
41 | |
42 | DirectedNetInterface::DirectedNetInterface() { |
43 | } |
44 | |
45 | DirectedNetInterface::~DirectedNetInterface() { |
46 | } |
47 | |
48 | |
49 | ////////// DirectedNetInterfaceSet ////////// |
50 | |
51 | DirectedNetInterfaceSet::DirectedNetInterfaceSet() |
52 | : fTable(HashTable::create(ONE_WORD_HASH_KEYS)) { |
53 | } |
54 | |
55 | DirectedNetInterfaceSet::~DirectedNetInterfaceSet() { |
56 | delete fTable; |
57 | } |
58 | |
59 | DirectedNetInterface* |
60 | DirectedNetInterfaceSet::Add(DirectedNetInterface const* interf) { |
61 | return (DirectedNetInterface*) fTable->Add((char*)interf, (void*)interf); |
62 | } |
63 | |
64 | Boolean |
65 | DirectedNetInterfaceSet::Remove(DirectedNetInterface const* interf) { |
66 | return fTable->Remove((char*)interf); |
67 | } |
68 | |
69 | DirectedNetInterfaceSet::Iterator:: |
70 | Iterator(DirectedNetInterfaceSet& interfaces) |
71 | : fIter(HashTable::Iterator::create(*(interfaces.fTable))) { |
72 | } |
73 | |
74 | DirectedNetInterfaceSet::Iterator::~Iterator() { |
75 | delete fIter; |
76 | } |
77 | |
78 | DirectedNetInterface* DirectedNetInterfaceSet::Iterator::next() { |
79 | char const* key; // dummy |
80 | return (DirectedNetInterface*) fIter->next(key); |
81 | }; |
82 | |
83 | |
84 | ////////// Socket ////////// |
85 | |
86 | int Socket::DebugLevel = 1; // default value |
87 | |
88 | Socket::Socket(UsageEnvironment& env, Port port) |
89 | : fEnv(DefaultUsageEnvironment != NULL ? *DefaultUsageEnvironment : env), fPort(port) { |
90 | fSocketNum = setupDatagramSocket(fEnv, port); |
91 | } |
92 | |
93 | void Socket::reset() { |
94 | if (fSocketNum >= 0) closeSocket(fSocketNum); |
95 | fSocketNum = -1; |
96 | } |
97 | |
98 | Socket::~Socket() { |
99 | reset(); |
100 | } |
101 | |
102 | Boolean 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 | |
122 | UsageEnvironment& operator<<(UsageEnvironment& s, const Socket& sock) { |
123 | return s << timestampString() << " Socket(" << sock.socketNum() << ")" ; |
124 | } |
125 | |
126 | ////////// SocketLookupTable ////////// |
127 | |
128 | SocketLookupTable::SocketLookupTable() |
129 | : fTable(HashTable::create(ONE_WORD_HASH_KEYS)) { |
130 | } |
131 | |
132 | SocketLookupTable::~SocketLookupTable() { |
133 | delete fTable; |
134 | } |
135 | |
136 | Socket* 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 | |
157 | Boolean SocketLookupTable::Remove(Socket const* sock) { |
158 | return fTable->Remove( (char*)(long)(sock->port().num()) ); |
159 | } |
160 | |
161 | ////////// NetInterfaceTrafficStats ////////// |
162 | |
163 | NetInterfaceTrafficStats::NetInterfaceTrafficStats() { |
164 | fTotNumPackets = fTotNumBytes = 0.0; |
165 | } |
166 | |
167 | void NetInterfaceTrafficStats::countPacket(unsigned packetSize) { |
168 | fTotNumPackets += 1.0; |
169 | fTotNumBytes += packetSize; |
170 | } |
171 | |
172 | Boolean NetInterfaceTrafficStats::haveSeenTraffic() const { |
173 | return fTotNumPackets != 0.0; |
174 | } |
175 | |