~ubuntu-branches/ubuntu/quantal/znc/quantal

« back to all changes in this revision

Viewing changes to .pc/01-fix-bouncedcc-dos.diff/modules/bouncedcc.cpp

  • Committer: Package Import Robot
  • Author(s): Patrick Matthäi
  • Date: 2012-01-25 15:03:14 UTC
  • mfrom: (25.1.4 sid)
  • Revision ID: package-import@ubuntu.com-20120125150314-4wr8vj3ovjeidn3m
Tags: 0.204-1
* New upstream release.
  - Drop patch 01-fix-bouncedcc-dos, it is included in this release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Copyright (C) 2004-2011  See the AUTHORS file for details.
3
 
 *
4
 
 * This program is free software; you can redistribute it and/or modify it
5
 
 * under the terms of the GNU General Public License version 2 as published
6
 
 * by the Free Software Foundation.
7
 
 */
8
 
 
9
 
#include "zncconfig.h"
10
 
#include "znc.h"
11
 
#include "User.h"
12
 
#include "Modules.h"
13
 
#include "Socket.h"
14
 
#include "FileUtils.h"
15
 
 
16
 
class CBounceDCCMod;
17
 
 
18
 
class CDCCBounce : public CSocket {
19
 
public:
20
 
        CDCCBounce(CBounceDCCMod* pMod, unsigned long uLongIP, unsigned short uPort,
21
 
                        const CString& sFileName, const CString& sRemoteNick,
22
 
                        const CString& sRemoteIP, bool bIsChat = false);
23
 
        CDCCBounce(CBounceDCCMod* pMod, const CString& sHostname, unsigned short uPort,
24
 
                        const CString& sRemoteNick, const CString& sRemoteIP,
25
 
                        const CString& sFileName, int iTimeout = 60, bool bIsChat = false);
26
 
        virtual ~CDCCBounce();
27
 
 
28
 
        static unsigned short DCCRequest(const CString& sNick, unsigned long uLongIP, unsigned short uPort, const CString& sFileName, bool bIsChat, CBounceDCCMod* pMod, const CString& sRemoteIP);
29
 
 
30
 
        void ReadLine(const CString& sData);
31
 
        virtual void ReadData(const char* data, size_t len);
32
 
        virtual void ReadPaused();
33
 
        virtual void Timeout();
34
 
        virtual void ConnectionRefused();
35
 
        virtual void ReachedMaxBuffer();
36
 
        virtual void SockError(int iErrno);
37
 
        virtual void Connected();
38
 
        virtual void Disconnected();
39
 
        virtual Csock* GetSockObj(const CString& sHost, unsigned short uPort);
40
 
        void Shutdown();
41
 
        void PutServ(const CString& sLine);
42
 
        void PutPeer(const CString& sLine);
43
 
        bool IsPeerConnected() { return (m_pPeer) ? m_pPeer->IsConnected() : false; }
44
 
 
45
 
        // Setters
46
 
        void SetPeer(CDCCBounce* p) { m_pPeer = p; }
47
 
        void SetRemoteIP(const CString& s) { m_sRemoteIP = s; }
48
 
        void SetRemoteNick(const CString& s) { m_sRemoteNick = s; }
49
 
        void SetRemote(bool b) { m_bIsRemote = b; }
50
 
        // !Setters
51
 
 
52
 
        // Getters
53
 
        unsigned short GetUserPort() const { return m_uRemotePort; }
54
 
        const CString& GetRemoteIP() const { return m_sRemoteIP; }
55
 
        const CString& GetRemoteNick() const { return m_sRemoteNick; }
56
 
        const CString& GetFileName() const { return m_sFileName; }
57
 
        CDCCBounce* GetPeer() const { return m_pPeer; }
58
 
        bool IsRemote() { return m_bIsRemote; }
59
 
        bool IsChat() { return m_bIsChat; }
60
 
        // !Getters
61
 
private:
62
 
protected:
63
 
        CString                      m_sRemoteNick;
64
 
        CString                      m_sRemoteIP;
65
 
        CString                      m_sConnectIP;
66
 
        CString                      m_sLocalIP;
67
 
        CString                      m_sFileName;
68
 
        CBounceDCCMod*               m_pModule;
69
 
        CDCCBounce*                  m_pPeer;
70
 
        unsigned short               m_uRemotePort;
71
 
        bool                         m_bIsChat;
72
 
        bool                         m_bIsRemote;
73
 
 
74
 
        static const unsigned int    m_uiMaxDCCBuffer;
75
 
        static const unsigned int    m_uiMinDCCBuffer;
76
 
};
77
 
 
78
 
// If we buffer more than this in memory, we will throttle the receiving side
79
 
const unsigned int CDCCBounce::m_uiMaxDCCBuffer = 10 * 1024;
80
 
// If less than this is in the buffer, the receiving side continues
81
 
const unsigned int CDCCBounce::m_uiMinDCCBuffer = 2 * 1024;
82
 
 
83
 
class CBounceDCCMod : public CModule {
84
 
public:
85
 
        void ListDCCsCommand(const CString& sLine) {
86
 
                CTable Table;
87
 
                Table.AddColumn("Type");
88
 
                Table.AddColumn("State");
89
 
                Table.AddColumn("Speed");
90
 
                Table.AddColumn("Nick");
91
 
                Table.AddColumn("IP");
92
 
                Table.AddColumn("File");
93
 
 
94
 
                set<CSocket*>::const_iterator it;
95
 
                for (it = BeginSockets(); it != EndSockets(); ++it) {
96
 
                        CDCCBounce* pSock = (CDCCBounce*) *it;
97
 
                        CString sSockName = pSock->GetSockName();
98
 
 
99
 
                        if (!(pSock->IsRemote())) {
100
 
                                Table.AddRow();
101
 
                                Table.SetCell("Nick", pSock->GetRemoteNick());
102
 
                                Table.SetCell("IP", pSock->GetRemoteIP());
103
 
 
104
 
                                if (pSock->IsChat()) {
105
 
                                        Table.SetCell("Type", "Chat");
106
 
                                } else {
107
 
                                        Table.SetCell("Type", "Xfer");
108
 
                                        Table.SetCell("File", pSock->GetFileName());
109
 
                                }
110
 
 
111
 
                                CString sState = "Waiting";
112
 
                                if ((pSock->IsConnected()) || (pSock->IsPeerConnected())) {
113
 
                                        sState = "Halfway";
114
 
                                        if ((pSock->IsPeerConnected()) && (pSock->IsPeerConnected())) {
115
 
                                                sState = "Connected";
116
 
                                        }
117
 
                                }
118
 
                                Table.SetCell("State", sState);
119
 
                        }
120
 
                }
121
 
 
122
 
                if (PutModule(Table) == 0) {
123
 
                        PutModule("You have no active DCCs.");
124
 
                }
125
 
        }
126
 
 
127
 
        void UseClientIPCommand(const CString& sLine) {
128
 
                CString sValue = sLine.Token(1, true);
129
 
 
130
 
                if (!sValue.empty()) {
131
 
                        SetNV("UseClientIP", sValue);
132
 
                }
133
 
 
134
 
                PutModule("UseClientIP: " + CString(GetNV("UseClientIP").ToBool()));
135
 
        }
136
 
 
137
 
        MODCONSTRUCTOR(CBounceDCCMod) {
138
 
                AddHelpCommand();
139
 
                AddCommand("ListDCCs", static_cast<CModCommand::ModCmdFunc>(&CBounceDCCMod::ListDCCsCommand),
140
 
                        "", "List all active DCCs");
141
 
                AddCommand("UseClientIP", static_cast<CModCommand::ModCmdFunc>(&CBounceDCCMod::UseClientIPCommand),
142
 
                        "<true|false>");
143
 
        }
144
 
 
145
 
        virtual ~CBounceDCCMod() {}
146
 
 
147
 
        CString GetLocalDCCIP() {
148
 
                return m_pUser->GetLocalDCCIP();
149
 
        }
150
 
 
151
 
        bool UseClientIP() {
152
 
                return GetNV("UseClientIP").ToBool();
153
 
        }
154
 
 
155
 
        virtual EModRet OnUserCTCP(CString& sTarget, CString& sMessage) {
156
 
                if (sMessage.Equals("DCC ", false, 4)) {
157
 
                        CString sType = sMessage.Token(1);
158
 
                        CString sFile = sMessage.Token(2);
159
 
                        unsigned long uLongIP = sMessage.Token(3).ToULong();
160
 
                        unsigned short uPort = sMessage.Token(4).ToUShort();
161
 
                        unsigned long uFileSize = sMessage.Token(5).ToULong();
162
 
                        CString sIP = GetLocalDCCIP();
163
 
 
164
 
                        if (!UseClientIP()) {
165
 
                                uLongIP = CUtils::GetLongIP(m_pClient->GetRemoteIP());
166
 
                        }
167
 
 
168
 
                        if (sType.Equals("CHAT")) {
169
 
                                unsigned short uBNCPort = CDCCBounce::DCCRequest(sTarget, uLongIP, uPort, "", true, this, "");
170
 
                                if (uBNCPort) {
171
 
                                        PutIRC("PRIVMSG " + sTarget + " :\001DCC CHAT chat " + CString(CUtils::GetLongIP(sIP)) + " " + CString(uBNCPort) + "\001");
172
 
                                }
173
 
                        } else if (sType.Equals("SEND")) {
174
 
                                // DCC SEND readme.txt 403120438 5550 1104
175
 
                                unsigned short uBNCPort = CDCCBounce::DCCRequest(sTarget, uLongIP, uPort, sFile, false, this, "");
176
 
                                if (uBNCPort) {
177
 
                                        PutIRC("PRIVMSG " + sTarget + " :\001DCC SEND " + sFile + " " + CString(CUtils::GetLongIP(sIP)) + " " + CString(uBNCPort) + " " + CString(uFileSize) + "\001");
178
 
                                }
179
 
                        } else if (sType.Equals("RESUME")) {
180
 
                                // PRIVMSG user :DCC RESUME "znc.o" 58810 151552
181
 
                                unsigned short uResumePort = sMessage.Token(3).ToUShort();
182
 
 
183
 
                                set<CSocket*>::const_iterator it;
184
 
                                for (it = BeginSockets(); it != EndSockets(); ++it) {
185
 
                                        CDCCBounce* pSock = (CDCCBounce*) *it;
186
 
 
187
 
                                        if (pSock->GetLocalPort() == uResumePort) {
188
 
                                                PutIRC("PRIVMSG " + sTarget + " :\001DCC " + sType + " " + sFile + " " + CString(pSock->GetUserPort()) + " " + sMessage.Token(4) + "\001");
189
 
                                        }
190
 
                                }
191
 
                        } else if (sType.Equals("ACCEPT")) {
192
 
                                // Need to lookup the connection by port, filter the port, and forward to the user
193
 
 
194
 
                                set<CSocket*>::const_iterator it;
195
 
                                for (it = BeginSockets(); it != EndSockets(); ++it) {
196
 
                                        CDCCBounce* pSock = (CDCCBounce*) *it;
197
 
                                        if (pSock->GetUserPort() == sMessage.Token(3).ToUShort()) {
198
 
                                                PutIRC("PRIVMSG " + sTarget + " :\001DCC " + sType + " " + sFile + " " + CString(pSock->GetLocalPort()) + " " + sMessage.Token(4) + "\001");
199
 
                                        }
200
 
                                }
201
 
                        }
202
 
 
203
 
                        return HALTCORE;
204
 
                }
205
 
 
206
 
                return CONTINUE;
207
 
        }
208
 
 
209
 
        virtual EModRet OnPrivCTCP(CNick& Nick, CString& sMessage) {
210
 
                if (sMessage.Equals("DCC ", false, 4) && m_pUser->IsUserAttached()) {
211
 
                        // DCC CHAT chat 2453612361 44592
212
 
                        CString sType = sMessage.Token(1);
213
 
                        CString sFile = sMessage.Token(2);
214
 
                        unsigned long uLongIP = sMessage.Token(3).ToULong();
215
 
                        unsigned short uPort = sMessage.Token(4).ToUShort();
216
 
                        unsigned long uFileSize = sMessage.Token(5).ToULong();
217
 
 
218
 
                        if (sType.Equals("CHAT")) {
219
 
                                CNick FromNick(Nick.GetNickMask());
220
 
                                unsigned short uBNCPort = CDCCBounce::DCCRequest(FromNick.GetNick(), uLongIP, uPort, "", true, this, CUtils::GetIP(uLongIP));
221
 
                                if (uBNCPort) {
222
 
                                        CString sIP = GetLocalDCCIP();
223
 
                                        m_pUser->PutUser(":" + Nick.GetNickMask() + " PRIVMSG " + m_pUser->GetNick() + " :\001DCC CHAT chat " + CString(CUtils::GetLongIP(sIP)) + " " + CString(uBNCPort) + "\001");
224
 
                                }
225
 
                        } else if (sType.Equals("SEND")) {
226
 
                                // DCC SEND readme.txt 403120438 5550 1104
227
 
                                unsigned short uBNCPort = CDCCBounce::DCCRequest(Nick.GetNick(), uLongIP, uPort, sFile, false, this, CUtils::GetIP(uLongIP));
228
 
                                if (uBNCPort) {
229
 
                                        CString sIP = GetLocalDCCIP();
230
 
                                        m_pUser->PutUser(":" + Nick.GetNickMask() + " PRIVMSG " + m_pUser->GetNick() + " :\001DCC SEND " + sFile + " " + CString(CUtils::GetLongIP(sIP)) + " " + CString(uBNCPort) + " " + CString(uFileSize) + "\001");
231
 
                                }
232
 
                        } else if (sType.Equals("RESUME")) {
233
 
                                // Need to lookup the connection by port, filter the port, and forward to the user
234
 
                                unsigned short uResumePort = sMessage.Token(3).ToUShort();
235
 
 
236
 
                                set<CSocket*>::const_iterator it;
237
 
                                for (it = BeginSockets(); it != EndSockets(); ++it) {
238
 
                                        CDCCBounce* pSock = (CDCCBounce*) *it;
239
 
 
240
 
                                        if (pSock->GetLocalPort() == uResumePort) {
241
 
                                                m_pUser->PutUser(":" + Nick.GetNickMask() + " PRIVMSG " + m_pClient->GetNick() + " :\001DCC " + sType + " " + sFile + " " + CString(pSock->GetUserPort()) + " " + sMessage.Token(4) + "\001");
242
 
                                        }
243
 
                                }
244
 
                        } else if (sType.Equals("ACCEPT")) {
245
 
                                // Need to lookup the connection by port, filter the port, and forward to the user
246
 
                                set<CSocket*>::const_iterator it;
247
 
                                for (it = BeginSockets(); it != EndSockets(); ++it) {
248
 
                                        CDCCBounce* pSock = (CDCCBounce*) *it;
249
 
 
250
 
                                        if (pSock->GetUserPort() == sMessage.Token(3).ToUShort()) {
251
 
                                                m_pUser->PutUser(":" + Nick.GetNickMask() + " PRIVMSG " + m_pClient->GetNick() + " :\001DCC " + sType + " " + sFile + " " + CString(pSock->GetLocalPort()) + " " + sMessage.Token(4) + "\001");
252
 
                                        }
253
 
                                }
254
 
                        }
255
 
 
256
 
                        return HALTCORE;
257
 
                }
258
 
 
259
 
                return CONTINUE;
260
 
        }
261
 
};
262
 
 
263
 
CDCCBounce::CDCCBounce(CBounceDCCMod* pMod, unsigned long uLongIP, unsigned short uPort,
264
 
                const CString& sFileName, const CString& sRemoteNick,
265
 
                const CString& sRemoteIP, bool bIsChat) : CSocket(pMod) {
266
 
        m_uRemotePort = uPort;
267
 
        m_sConnectIP = CUtils::GetIP(uLongIP);
268
 
        m_sRemoteIP = sRemoteIP;
269
 
        m_sFileName = sFileName;
270
 
        m_sRemoteNick = sRemoteNick;
271
 
        m_pModule = pMod;
272
 
        m_bIsChat = bIsChat;
273
 
        m_sLocalIP = pMod->GetLocalDCCIP();
274
 
        m_pPeer = NULL;
275
 
        m_bIsRemote = false;
276
 
 
277
 
        if (bIsChat) {
278
 
                EnableReadLine();
279
 
        } else {
280
 
                DisableReadLine();
281
 
        }
282
 
}
283
 
 
284
 
CDCCBounce::CDCCBounce(CBounceDCCMod* pMod, const CString& sHostname, unsigned short uPort,
285
 
                const CString& sRemoteNick, const CString& sRemoteIP, const CString& sFileName,
286
 
                int iTimeout, bool bIsChat) : CSocket(pMod, sHostname, uPort, iTimeout) {
287
 
        m_uRemotePort = 0;
288
 
        m_bIsChat = bIsChat;
289
 
        m_pModule = pMod;
290
 
        m_pPeer = NULL;
291
 
        m_sRemoteNick = sRemoteNick;
292
 
        m_sFileName = sFileName;
293
 
        m_sRemoteIP = sRemoteIP;
294
 
        m_bIsRemote = false;
295
 
 
296
 
        SetMaxBufferThreshold(10240);
297
 
        if (bIsChat) {
298
 
                EnableReadLine();
299
 
        } else {
300
 
                DisableReadLine();
301
 
        }
302
 
}
303
 
 
304
 
CDCCBounce::~CDCCBounce() {
305
 
        if (m_pPeer) {
306
 
                m_pPeer->Shutdown();
307
 
                m_pPeer = NULL;
308
 
        }
309
 
}
310
 
 
311
 
void CDCCBounce::ReadLine(const CString& sData) {
312
 
        CString sLine = sData.TrimRight_n("\r\n");
313
 
 
314
 
        DEBUG(GetSockName() << " <- [" << sLine << "]");
315
 
 
316
 
        PutPeer(sLine);
317
 
}
318
 
 
319
 
void CDCCBounce::ReachedMaxBuffer() {
320
 
        DEBUG(GetSockName() << " == ReachedMaxBuffer()");
321
 
 
322
 
        CString sType = (m_bIsChat) ? "Chat" : "Xfer";
323
 
 
324
 
        m_pModule->PutModule("DCC " + sType + " Bounce (" + m_sRemoteNick + "): Too long line received");
325
 
        Close();
326
 
}
327
 
 
328
 
void CDCCBounce::ReadData(const char* data, size_t len) {
329
 
        if (m_pPeer) {
330
 
                m_pPeer->Write(data, len);
331
 
 
332
 
                size_t BufLen = m_pPeer->GetInternalWriteBuffer().length();
333
 
 
334
 
                if (BufLen >= m_uiMaxDCCBuffer) {
335
 
                        DEBUG(GetSockName() << " The send buffer is over the "
336
 
                                        "limit (" << BufLen <<"), throttling");
337
 
                        PauseRead();
338
 
                }
339
 
        }
340
 
}
341
 
 
342
 
void CDCCBounce::ReadPaused() {
343
 
        if (!m_pPeer || m_pPeer->GetInternalWriteBuffer().length() <= m_uiMinDCCBuffer)
344
 
                UnPauseRead();
345
 
}
346
 
 
347
 
void CDCCBounce::Timeout() {
348
 
        DEBUG(GetSockName() << " == Timeout()");
349
 
        CString sType = (m_bIsChat) ? "Chat" : "Xfer";
350
 
 
351
 
        if (IsRemote()) {
352
 
                CString sHost = Csock::GetHostName();
353
 
                if (!sHost.empty()) {
354
 
                        sHost = " to [" + sHost + " " + CString(Csock::GetPort()) + "]";
355
 
                } else {
356
 
                        sHost = ".";
357
 
                }
358
 
 
359
 
                m_pModule->PutModule("DCC " + sType + " Bounce (" + m_sRemoteNick + "): Timeout while connecting" + sHost);
360
 
        } else {
361
 
                m_pModule->PutModule("DCC " + sType + " Bounce (" + m_sRemoteNick + "): Timeout waiting for incoming connection [" + Csock::GetLocalIP() + ":" + CString(Csock::GetLocalPort()) + "]");
362
 
        }
363
 
}
364
 
 
365
 
void CDCCBounce::ConnectionRefused() {
366
 
        DEBUG(GetSockName() << " == ConnectionRefused()");
367
 
 
368
 
        CString sType = (m_bIsChat) ? "Chat" : "Xfer";
369
 
        CString sHost = Csock::GetHostName();
370
 
        if (!sHost.empty()) {
371
 
                sHost = " to [" + sHost + " " + CString(Csock::GetPort()) + "]";
372
 
        } else {
373
 
                sHost = ".";
374
 
        }
375
 
 
376
 
        m_pModule->PutModule("DCC " + sType + " Bounce (" + m_sRemoteNick + "): Connection Refused while connecting" + sHost);
377
 
}
378
 
 
379
 
void CDCCBounce::SockError(int iErrno) {
380
 
        DEBUG(GetSockName() << " == SockError(" << iErrno << ")");
381
 
        CString sType = (m_bIsChat) ? "Chat" : "Xfer";
382
 
 
383
 
        if (IsRemote()) {
384
 
                CString sHost = Csock::GetHostName();
385
 
                if (!sHost.empty()) {
386
 
                        sHost = "[" + sHost + " " + CString(Csock::GetPort()) + "]";
387
 
                }
388
 
 
389
 
                m_pModule->PutModule("DCC " + sType + " Bounce (" + m_sRemoteNick + "): Socket error [" + CString(strerror(iErrno)) + "]" + sHost);
390
 
        } else {
391
 
                m_pModule->PutModule("DCC " + sType + " Bounce (" + m_sRemoteNick + "): Socket error [" + CString(strerror(iErrno)) + "] [" + Csock::GetLocalIP() + ":" + CString(Csock::GetLocalPort()) + "]");
392
 
        }
393
 
}
394
 
 
395
 
void CDCCBounce::Connected() {
396
 
        SetTimeout(0);
397
 
        DEBUG(GetSockName() << " == Connected()");
398
 
}
399
 
 
400
 
void CDCCBounce::Disconnected() {
401
 
        DEBUG(GetSockName() << " == Disconnected()");
402
 
}
403
 
 
404
 
void CDCCBounce::Shutdown() {
405
 
        m_pPeer = NULL;
406
 
        DEBUG(GetSockName() << " == Close(); because my peer told me to");
407
 
        Close();
408
 
}
409
 
 
410
 
Csock* CDCCBounce::GetSockObj(const CString& sHost, unsigned short uPort) {
411
 
        Close();
412
 
 
413
 
        if (m_sRemoteIP.empty()) {
414
 
                m_sRemoteIP = sHost;
415
 
        }
416
 
 
417
 
        CDCCBounce* pSock = new CDCCBounce(m_pModule, sHost, uPort, m_sRemoteNick, m_sRemoteIP, m_sFileName, m_bIsChat);
418
 
        CDCCBounce* pRemoteSock = new CDCCBounce(m_pModule, sHost, uPort, m_sRemoteNick, m_sRemoteIP, m_sFileName, m_bIsChat);
419
 
        pSock->SetPeer(pRemoteSock);
420
 
        pRemoteSock->SetPeer(pSock);
421
 
        pRemoteSock->SetRemote(true);
422
 
        pSock->SetRemote(false);
423
 
 
424
 
        if (!CZNC::Get().GetManager().Connect(m_sConnectIP, m_uRemotePort, "DCC::" + CString((m_bIsChat) ? "Chat" : "XFER") + "::Remote::" + m_sRemoteNick, 60, false, m_sLocalIP, pRemoteSock)) {
425
 
                pRemoteSock->Close();
426
 
        }
427
 
 
428
 
        pSock->SetSockName(GetSockName());
429
 
        return pSock;
430
 
}
431
 
 
432
 
void CDCCBounce::PutServ(const CString& sLine) {
433
 
        DEBUG(GetSockName() << " -> [" << sLine << "]");
434
 
        Write(sLine + "\r\n");
435
 
}
436
 
 
437
 
void CDCCBounce::PutPeer(const CString& sLine) {
438
 
        if (m_pPeer) {
439
 
                m_pPeer->PutServ(sLine);
440
 
        } else {
441
 
                PutServ("*** Not connected yet ***");
442
 
        }
443
 
}
444
 
 
445
 
unsigned short CDCCBounce::DCCRequest(const CString& sNick, unsigned long uLongIP, unsigned short uPort, const CString& sFileName, bool bIsChat, CBounceDCCMod* pMod, const CString& sRemoteIP) {
446
 
        CDCCBounce* pDCCBounce = new CDCCBounce(pMod, uLongIP, uPort, sFileName, sNick, sRemoteIP, bIsChat);
447
 
        unsigned short uListenPort = CZNC::Get().GetManager().ListenRand("DCC::" + CString((bIsChat) ? "Chat" : "Xfer") + "::Local::" + sNick,
448
 
                        pMod->GetLocalDCCIP(), false, SOMAXCONN, pDCCBounce, 120);
449
 
 
450
 
        return uListenPort;
451
 
}
452
 
 
453
 
 
454
 
 
455
 
MODULEDEFS(CBounceDCCMod, "Bounce DCC module")
456