mirror of
https://github.com/znc/znc.git
synced 2026-07-04 08:51:14 +02:00
Migrate dcc bouncing to its own module
This commit is contained in:
+6
-91
@@ -8,7 +8,6 @@
|
||||
|
||||
#include "Client.h"
|
||||
#include "Chan.h"
|
||||
#include "DCCBounce.h"
|
||||
#include "FileUtils.h"
|
||||
#include "IRCSock.h"
|
||||
#include "User.h"
|
||||
@@ -315,14 +314,6 @@ void CClient::ReadLine(const CString& sData) {
|
||||
return;
|
||||
}
|
||||
|
||||
// No idea what this is supposed to do, but it doesn't seem to
|
||||
// make sense. Comment this out and wait for complaints.
|
||||
#if 0
|
||||
if (sMsg.WildCmp("DCC * (*)")) {
|
||||
sMsg = "DCC " + sLine.Token(3) + " (" + ((GetIRCSock()) ? GetIRCSock()->GetLocalIP() : GetLocalIP()) + ")";
|
||||
}
|
||||
#endif
|
||||
|
||||
if (sMsg.WildCmp("\001*\001")) {
|
||||
CString sCTCP = sMsg;
|
||||
sCTCP.LeftChomp();
|
||||
@@ -377,95 +368,19 @@ void CClient::ReadLine(const CString& sData) {
|
||||
sCTCP.LeftChomp();
|
||||
sCTCP.RightChomp();
|
||||
|
||||
if (sCTCP.Equals("DCC ", false, 4) && m_pUser->BounceDCCs()) {
|
||||
CString sType = sCTCP.Token(1);
|
||||
CString sFile = sCTCP.Token(2);
|
||||
unsigned long uLongIP = sCTCP.Token(3).ToULong();
|
||||
unsigned short uPort = sCTCP.Token(4).ToUShort();
|
||||
unsigned long uFileSize = sCTCP.Token(5).ToULong();
|
||||
CString sIP = m_pUser->GetLocalDCCIP();
|
||||
|
||||
if (!m_pUser->UseClientIP()) {
|
||||
uLongIP = CUtils::GetLongIP(GetRemoteIP());
|
||||
}
|
||||
|
||||
if (sType.Equals("CHAT")) {
|
||||
if (!sTarget.TrimPrefix(m_pUser->GetStatusPrefix())) {
|
||||
unsigned short uBNCPort = CDCCBounce::DCCRequest(sTarget, uLongIP, uPort, "", true, m_pUser, "");
|
||||
if (uBNCPort) {
|
||||
PutIRC("PRIVMSG " + sTarget + " :\001DCC CHAT chat " + CString(CUtils::GetLongIP(sIP)) + " " + CString(uBNCPort) + "\001");
|
||||
}
|
||||
}
|
||||
} else if (sType.Equals("SEND")) {
|
||||
// DCC SEND readme.txt 403120438 5550 1104
|
||||
|
||||
if (sTarget.TrimPrefix(m_pUser->GetStatusPrefix())) {
|
||||
if (sTarget.Equals("status")) {
|
||||
CString sPath = m_pUser->GetDLPath();
|
||||
if (!CFile::Exists(sPath)) {
|
||||
PutStatus("Could not create [" + sPath + "] directory.");
|
||||
return;
|
||||
} else if (!CFile::IsDir(sPath)) {
|
||||
PutStatus("Error: [" + sPath + "] is not a directory.");
|
||||
return;
|
||||
}
|
||||
|
||||
CString sAbsolutePath = CDir::CheckPathPrefix(sPath, sFile);
|
||||
|
||||
if (sAbsolutePath.empty()) {
|
||||
PutStatus("Illegal path.");
|
||||
return;
|
||||
}
|
||||
|
||||
m_pUser->GetFile(GetNick(), CUtils::GetIP(uLongIP), uPort, sAbsolutePath, uFileSize);
|
||||
}
|
||||
} else {
|
||||
unsigned short uBNCPort = CDCCBounce::DCCRequest(sTarget, uLongIP, uPort, sFile, false, m_pUser, "");
|
||||
if (uBNCPort) {
|
||||
PutIRC("PRIVMSG " + sTarget + " :\001DCC SEND " + sFile + " " + CString(CUtils::GetLongIP(sIP)) + " " + CString(uBNCPort) + " " + CString(uFileSize) + "\001");
|
||||
}
|
||||
}
|
||||
} else if (sType.Equals("RESUME")) {
|
||||
// PRIVMSG user :DCC RESUME "znc.o" 58810 151552
|
||||
if (sTarget.TrimPrefix(m_pUser->GetStatusPrefix())) {
|
||||
if (sCTCP.Equals("DCC RESUME ", false, 11)) {
|
||||
CString sFile = sCTCP.Token(2);
|
||||
unsigned short uResumePort = sCTCP.Token(3).ToUShort();
|
||||
unsigned long uResumeSize = sCTCP.Token(4).ToULong();
|
||||
|
||||
// Need to lookup the connection by port, filter the port, and forward to the user
|
||||
CString sStatusPrefix = m_pUser->GetStatusPrefix();
|
||||
if (sTarget.Equals(sStatusPrefix, false, sStatusPrefix.length())) {
|
||||
if (m_pUser->ResumeFile(uResumePort, uResumeSize)) {
|
||||
PutClient(":" + sTarget + "!znc@znc.in PRIVMSG " + GetNick() + " :\001DCC ACCEPT " + sFile + " " + CString(uResumePort) + " " + CString(uResumeSize) + "\001");
|
||||
} else {
|
||||
PutStatus("DCC -> [" + GetNick() + "][" + sFile + "] Unable to find send to initiate resume.");
|
||||
}
|
||||
if (m_pUser->ResumeFile(uResumePort, uResumeSize)) {
|
||||
PutClient(":" + sTarget + "!znc@znc.in PRIVMSG " + GetNick() + " :\001DCC ACCEPT " + sFile + " " + CString(uResumePort) + " " + CString(uResumeSize) + "\001");
|
||||
} else {
|
||||
CDCCBounce* pSock = (CDCCBounce*) CZNC::Get().GetManager().FindSockByLocalPort(uResumePort);
|
||||
if (pSock && pSock->GetSockName().Equals("DCC::", false, 5)) {
|
||||
PutIRC("PRIVMSG " + sTarget + " :\001DCC " + sType + " " + sFile + " " + CString(pSock->GetUserPort()) + " " + sCTCP.Token(4) + "\001");
|
||||
}
|
||||
}
|
||||
} else if (sType.Equals("ACCEPT")) {
|
||||
CString sStatusPrefix = m_pUser->GetStatusPrefix();
|
||||
if (!sTarget.Equals(sStatusPrefix, false, sStatusPrefix.length())) {
|
||||
// Need to lookup the connection by port, filter the port, and forward to the user
|
||||
CSockManager& Manager = CZNC::Get().GetManager();
|
||||
|
||||
for (unsigned int a = 0; a < Manager.size(); a++) {
|
||||
CDCCBounce* pSock = (CDCCBounce*) Manager[a];
|
||||
|
||||
if (pSock && pSock->GetSockName().Equals("DCC::", false, 5)) {
|
||||
if (pSock->GetUserPort() == sCTCP.Token(3).ToUShort()) {
|
||||
PutIRC("PRIVMSG " + sTarget + " :\001DCC " + sType + " " + sFile + " " + CString(pSock->GetLocalPort()) + " " + sCTCP.Token(4) + "\001");
|
||||
}
|
||||
}
|
||||
}
|
||||
PutStatus("DCC -> [" + GetNick() + "][" + sFile + "] Unable to find send to initiate resume.");
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (sTarget.TrimPrefix(m_pUser->GetStatusPrefix())) {
|
||||
if (sTarget.Equals("status")) {
|
||||
StatusCTCP(sCTCP);
|
||||
} else {
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
|
||||
#include "Client.h"
|
||||
#include "Chan.h"
|
||||
#include "DCCBounce.h"
|
||||
#include "DCCSock.h"
|
||||
#include "FileUtils.h"
|
||||
#include "IRCSock.h"
|
||||
@@ -522,14 +521,6 @@ void CClient::UserCommand(CString& sLine) {
|
||||
CString sSockName = Manager[a]->GetSockName();
|
||||
|
||||
if (sSockName.TrimPrefix("DCC::")) {
|
||||
if (sSockName.Equals("XFER::REMOTE::", false, 14)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (sSockName.Equals("CHAT::REMOTE::", false, 14)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (sSockName.Equals("SEND", false, 4)) {
|
||||
CDCCSock* pSock = (CDCCSock*) Manager[a];
|
||||
|
||||
@@ -559,39 +550,6 @@ void CClient::UserCommand(CString& sLine) {
|
||||
Table.SetCell("Nick", pSock->GetRemoteNick());
|
||||
Table.SetCell("IP", pSock->GetRemoteIP());
|
||||
Table.SetCell("File", pSock->GetFileName());
|
||||
} else if (sSockName.Equals("XFER::LOCAL", false, 11)) {
|
||||
CDCCBounce* pSock = (CDCCBounce*) Manager[a];
|
||||
|
||||
CString sState = "Waiting";
|
||||
if ((pSock->IsConnected()) || (pSock->IsPeerConnected())) {
|
||||
sState = "Halfway";
|
||||
if ((pSock->IsPeerConnected()) && (pSock->IsPeerConnected())) {
|
||||
sState = "Connected";
|
||||
}
|
||||
}
|
||||
|
||||
Table.AddRow();
|
||||
Table.SetCell("Type", "Xfer");
|
||||
Table.SetCell("State", sState);
|
||||
Table.SetCell("Nick", pSock->GetRemoteNick());
|
||||
Table.SetCell("IP", pSock->GetRemoteIP());
|
||||
Table.SetCell("File", pSock->GetFileName());
|
||||
} else if (sSockName.Equals("CHAT::LOCAL", false, 11)) {
|
||||
CDCCBounce* pSock = (CDCCBounce*) Manager[a];
|
||||
|
||||
CString sState = "Waiting";
|
||||
if ((pSock->IsConnected()) || (pSock->IsPeerConnected())) {
|
||||
sState = "Halfway";
|
||||
if ((pSock->IsPeerConnected()) && (pSock->IsPeerConnected())) {
|
||||
sState = "Connected";
|
||||
}
|
||||
}
|
||||
|
||||
Table.AddRow();
|
||||
Table.SetCell("Type", "Chat");
|
||||
Table.SetCell("State", sState);
|
||||
Table.SetCell("Nick", pSock->GetRemoteNick());
|
||||
Table.SetCell("IP", pSock->GetRemoteIP());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
-213
@@ -1,213 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2011 See the AUTHORS file for details.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 as published
|
||||
* by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include "DCCBounce.h"
|
||||
#include "User.h"
|
||||
#include "znc.h"
|
||||
|
||||
// If we buffer more than this in memory, we will throttle the receiving side
|
||||
const unsigned int CDCCBounce::m_uiMaxDCCBuffer = 10 * 1024;
|
||||
// If less than this is in the buffer, the receiving side continues
|
||||
const unsigned int CDCCBounce::m_uiMinDCCBuffer = 2 * 1024;
|
||||
|
||||
CDCCBounce::CDCCBounce(CUser* pUser, unsigned long uLongIP, unsigned short uPort,
|
||||
const CString& sFileName, const CString& sRemoteNick,
|
||||
const CString& sRemoteIP, bool bIsChat) : CZNCSock() {
|
||||
m_uRemotePort = uPort;
|
||||
m_sConnectIP = CUtils::GetIP(uLongIP);
|
||||
m_sRemoteIP = sRemoteIP;
|
||||
m_sFileName = sFileName;
|
||||
m_sRemoteNick = sRemoteNick;
|
||||
m_pUser = pUser;
|
||||
m_bIsChat = bIsChat;
|
||||
m_sLocalIP = pUser->GetLocalDCCIP();
|
||||
m_pPeer = NULL;
|
||||
m_bIsRemote = false;
|
||||
|
||||
if (bIsChat) {
|
||||
EnableReadLine();
|
||||
}
|
||||
|
||||
m_pUser->AddDCCBounce(this);
|
||||
}
|
||||
|
||||
CDCCBounce::CDCCBounce(const CString& sHostname, unsigned short uPort, CUser* pUser,
|
||||
const CString& sRemoteNick, const CString& sRemoteIP, const CString& sFileName,
|
||||
int iTimeout, bool bIsChat) : CZNCSock(sHostname, uPort, iTimeout) {
|
||||
m_uRemotePort = 0;
|
||||
m_bIsChat = bIsChat;
|
||||
m_pUser = pUser;
|
||||
m_pPeer = NULL;
|
||||
m_sRemoteNick = sRemoteNick;
|
||||
m_sFileName = sFileName;
|
||||
m_sRemoteIP = sRemoteIP;
|
||||
m_bIsRemote = false;
|
||||
|
||||
SetMaxBufferThreshold(10240);
|
||||
if (bIsChat) {
|
||||
EnableReadLine();
|
||||
}
|
||||
|
||||
m_pUser->AddDCCBounce(this);
|
||||
}
|
||||
|
||||
CDCCBounce::~CDCCBounce() {
|
||||
if (m_pPeer) {
|
||||
m_pPeer->Shutdown();
|
||||
m_pPeer = NULL;
|
||||
}
|
||||
|
||||
m_pUser->AddBytesRead(GetBytesRead());
|
||||
m_pUser->AddBytesWritten(GetBytesWritten());
|
||||
|
||||
m_pUser->DelDCCBounce(this);
|
||||
}
|
||||
|
||||
void CDCCBounce::ReadLine(const CString& sData) {
|
||||
CString sLine = sData.TrimRight_n("\r\n");
|
||||
|
||||
DEBUG(GetSockName() << " <- [" << sLine << "]");
|
||||
|
||||
PutPeer(sLine);
|
||||
}
|
||||
|
||||
void CDCCBounce::ReachedMaxBuffer() {
|
||||
DEBUG(GetSockName() << " == ReachedMaxBuffer()");
|
||||
|
||||
CString sType = (m_bIsChat) ? "Chat" : "Xfer";
|
||||
|
||||
m_pUser->PutStatus("DCC " + sType + " Bounce (" + m_sRemoteNick + "): Too long line received");
|
||||
Close();
|
||||
}
|
||||
|
||||
void CDCCBounce::ReadData(const char* data, size_t len) {
|
||||
if (m_pPeer) {
|
||||
m_pPeer->Write(data, len);
|
||||
|
||||
size_t BufLen = m_pPeer->GetInternalWriteBuffer().length();
|
||||
|
||||
if (BufLen >= m_uiMaxDCCBuffer) {
|
||||
DEBUG(GetSockName() << " The send buffer is over the "
|
||||
"limit (" << BufLen <<"), throttling");
|
||||
PauseRead();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CDCCBounce::ReadPaused() {
|
||||
if (!m_pPeer || m_pPeer->GetInternalWriteBuffer().length() <= m_uiMinDCCBuffer)
|
||||
UnPauseRead();
|
||||
}
|
||||
|
||||
void CDCCBounce::Timeout() {
|
||||
DEBUG(GetSockName() << " == Timeout()");
|
||||
CString sType = (m_bIsChat) ? "Chat" : "Xfer";
|
||||
|
||||
if (IsRemote()) {
|
||||
CString sHost = Csock::GetHostName();
|
||||
if (!sHost.empty()) {
|
||||
sHost = " to [" + sHost + " " + CString(Csock::GetPort()) + "]";
|
||||
} else {
|
||||
sHost = ".";
|
||||
}
|
||||
|
||||
m_pUser->PutStatus("DCC " + sType + " Bounce (" + m_sRemoteNick + "): Timeout while connecting" + sHost);
|
||||
} else {
|
||||
m_pUser->PutStatus("DCC " + sType + " Bounce (" + m_sRemoteNick + "): Timeout waiting for incoming connection [" + Csock::GetLocalIP() + ":" + CString(Csock::GetLocalPort()) + "]");
|
||||
}
|
||||
}
|
||||
|
||||
void CDCCBounce::ConnectionRefused() {
|
||||
DEBUG(GetSockName() << " == ConnectionRefused()");
|
||||
|
||||
CString sType = (m_bIsChat) ? "Chat" : "Xfer";
|
||||
CString sHost = Csock::GetHostName();
|
||||
if (!sHost.empty()) {
|
||||
sHost = " to [" + sHost + " " + CString(Csock::GetPort()) + "]";
|
||||
} else {
|
||||
sHost = ".";
|
||||
}
|
||||
|
||||
m_pUser->PutStatus("DCC " + sType + " Bounce (" + m_sRemoteNick + "): Connection Refused while connecting" + sHost);
|
||||
}
|
||||
|
||||
void CDCCBounce::SockError(int iErrno) {
|
||||
DEBUG(GetSockName() << " == SockError(" << iErrno << ")");
|
||||
CString sType = (m_bIsChat) ? "Chat" : "Xfer";
|
||||
|
||||
if (IsRemote()) {
|
||||
CString sHost = Csock::GetHostName();
|
||||
if (!sHost.empty()) {
|
||||
sHost = "[" + sHost + " " + CString(Csock::GetPort()) + "]";
|
||||
}
|
||||
|
||||
m_pUser->PutStatus("DCC " + sType + " Bounce (" + m_sRemoteNick + "): Socket error [" + CString(strerror(iErrno)) + "]" + sHost);
|
||||
} else {
|
||||
m_pUser->PutStatus("DCC " + sType + " Bounce (" + m_sRemoteNick + "): Socket error [" + CString(strerror(iErrno)) + "] [" + Csock::GetLocalIP() + ":" + CString(Csock::GetLocalPort()) + "]");
|
||||
}
|
||||
}
|
||||
|
||||
void CDCCBounce::Connected() {
|
||||
DEBUG(GetSockName() << " == Connected()");
|
||||
SetTimeout(0);
|
||||
}
|
||||
|
||||
void CDCCBounce::Disconnected() {
|
||||
DEBUG(GetSockName() << " == Disconnected()");
|
||||
}
|
||||
|
||||
void CDCCBounce::Shutdown() {
|
||||
m_pPeer = NULL;
|
||||
DEBUG(GetSockName() << " == Close(); because my peer told me to");
|
||||
Close();
|
||||
}
|
||||
|
||||
Csock* CDCCBounce::GetSockObj(const CString& sHost, unsigned short uPort) {
|
||||
Close();
|
||||
|
||||
if (m_sRemoteIP.empty()) {
|
||||
m_sRemoteIP = sHost;
|
||||
}
|
||||
|
||||
CDCCBounce* pSock = new CDCCBounce(sHost, uPort, m_pUser, m_sRemoteNick, m_sRemoteIP, m_sFileName, m_bIsChat);
|
||||
CDCCBounce* pRemoteSock = new CDCCBounce(sHost, uPort, m_pUser, m_sRemoteNick, m_sRemoteIP, m_sFileName, m_bIsChat);
|
||||
pSock->SetPeer(pRemoteSock);
|
||||
pRemoteSock->SetPeer(pSock);
|
||||
pRemoteSock->SetRemote(true);
|
||||
pSock->SetRemote(false);
|
||||
|
||||
if (!CZNC::Get().GetManager().Connect(m_sConnectIP, m_uRemotePort, "DCC::" + CString((m_bIsChat) ? "Chat" : "XFER") + "::Remote::" + m_sRemoteNick, 60, false, m_sLocalIP, pRemoteSock)) {
|
||||
pRemoteSock->Close();
|
||||
}
|
||||
|
||||
pSock->SetSockName(GetSockName());
|
||||
pSock->SetTimeout(0);
|
||||
return pSock;
|
||||
}
|
||||
|
||||
void CDCCBounce::PutServ(const CString& sLine) {
|
||||
DEBUG(GetSockName() << " -> [" << sLine << "]");
|
||||
Write(sLine + "\r\n");
|
||||
}
|
||||
|
||||
void CDCCBounce::PutPeer(const CString& sLine) {
|
||||
if (m_pPeer) {
|
||||
m_pPeer->PutServ(sLine);
|
||||
} else {
|
||||
PutServ("*** Not connected yet ***");
|
||||
}
|
||||
}
|
||||
|
||||
unsigned short CDCCBounce::DCCRequest(const CString& sNick, unsigned long uLongIP, unsigned short uPort, const CString& sFileName, bool bIsChat, CUser* pUser, const CString& sRemoteIP) {
|
||||
CDCCBounce* pDCCBounce = new CDCCBounce(pUser, uLongIP, uPort, sFileName, sNick, sRemoteIP, bIsChat);
|
||||
unsigned short uListenPort = CZNC::Get().GetManager().ListenRand("DCC::" + CString((bIsChat) ? "Chat" : "Xfer") + "::Local::" + sNick,
|
||||
pUser->GetLocalDCCIP(), false, SOMAXCONN, pDCCBounce, 120);
|
||||
|
||||
return uListenPort;
|
||||
}
|
||||
|
||||
-77
@@ -1,77 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2011 See the AUTHORS file for details.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 as published
|
||||
* by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#ifndef _DCCBOUNCE_H
|
||||
#define _DCCBOUNCE_H
|
||||
|
||||
#include "zncconfig.h"
|
||||
#include "Socket.h"
|
||||
|
||||
class CUser;
|
||||
|
||||
class CDCCBounce : public CZNCSock {
|
||||
public:
|
||||
CDCCBounce(CUser* pUser, unsigned long uLongIP, unsigned short uPort,
|
||||
const CString& sFileName, const CString& sRemoteNick,
|
||||
const CString& sRemoteIP, bool bIsChat = false);
|
||||
CDCCBounce(const CString& sHostname, unsigned short uPort, CUser* pUser,
|
||||
const CString& sRemoteNick, const CString& sRemoteIP,
|
||||
const CString& sFileName, int iTimeout = 60, bool bIsChat = false);
|
||||
virtual ~CDCCBounce();
|
||||
|
||||
static unsigned short DCCRequest(const CString& sNick, unsigned long uLongIP, unsigned short uPort, const CString& sFileName, bool bIsChat, CUser* pUser, const CString& sRemoteIP);
|
||||
|
||||
void ReadLine(const CString& sData);
|
||||
virtual void ReadData(const char* data, size_t len);
|
||||
virtual void ReadPaused();
|
||||
virtual void Timeout();
|
||||
virtual void ConnectionRefused();
|
||||
virtual void ReachedMaxBuffer();
|
||||
virtual void SockError(int iErrno);
|
||||
virtual void Connected();
|
||||
virtual void Disconnected();
|
||||
virtual Csock* GetSockObj(const CString& sHost, unsigned short uPort);
|
||||
void Shutdown();
|
||||
void PutServ(const CString& sLine);
|
||||
void PutPeer(const CString& sLine);
|
||||
bool IsPeerConnected() { return (m_pPeer) ? m_pPeer->IsConnected() : false; }
|
||||
|
||||
// Setters
|
||||
void SetPeer(CDCCBounce* p) { m_pPeer = p; }
|
||||
void SetRemoteIP(const CString& s) { m_sRemoteIP = s; }
|
||||
void SetRemoteNick(const CString& s) { m_sRemoteNick = s; }
|
||||
void SetRemote(bool b) { m_bIsRemote = b; }
|
||||
// !Setters
|
||||
|
||||
// Getters
|
||||
unsigned short GetUserPort() const { return m_uRemotePort; }
|
||||
const CString& GetRemoteIP() const { return m_sRemoteIP; }
|
||||
const CString& GetRemoteNick() const { return m_sRemoteNick; }
|
||||
const CString& GetFileName() const { return m_sFileName; }
|
||||
CDCCBounce* GetPeer() const { return m_pPeer; }
|
||||
bool IsRemote() { return m_bIsRemote; }
|
||||
// !Getters
|
||||
private:
|
||||
protected:
|
||||
CString m_sRemoteNick;
|
||||
CString m_sRemoteIP;
|
||||
CString m_sConnectIP;
|
||||
CString m_sLocalIP;
|
||||
CString m_sFileName;
|
||||
CUser* m_pUser;
|
||||
CDCCBounce* m_pPeer;
|
||||
unsigned short m_uRemotePort;
|
||||
bool m_bIsChat;
|
||||
bool m_bIsRemote;
|
||||
|
||||
static const unsigned int m_uiMaxDCCBuffer;
|
||||
static const unsigned int m_uiMinDCCBuffer;
|
||||
};
|
||||
|
||||
#endif // !_DCCBOUNCE_H
|
||||
|
||||
-48
@@ -9,7 +9,6 @@
|
||||
#include "IRCSock.h"
|
||||
#include "Chan.h"
|
||||
#include "Client.h"
|
||||
#include "DCCBounce.h"
|
||||
#include "User.h"
|
||||
#include "znc.h"
|
||||
|
||||
@@ -768,53 +767,6 @@ bool CIRCSock::OnPrivCTCP(CNick& Nick, CString& sMessage) {
|
||||
sMessage = "ACTION " + sMessage;
|
||||
}
|
||||
|
||||
if (sMessage.Equals("DCC ", false, 4) && m_pUser && m_pUser->BounceDCCs() && m_pUser->IsUserAttached()) {
|
||||
// DCC CHAT chat 2453612361 44592
|
||||
CString sType = sMessage.Token(1);
|
||||
CString sFile = sMessage.Token(2);
|
||||
unsigned long uLongIP = sMessage.Token(3).ToULong();
|
||||
unsigned short uPort = sMessage.Token(4).ToUShort();
|
||||
unsigned long uFileSize = sMessage.Token(5).ToULong();
|
||||
|
||||
if (sType.Equals("CHAT")) {
|
||||
CNick FromNick(Nick.GetNickMask());
|
||||
unsigned short uBNCPort = CDCCBounce::DCCRequest(FromNick.GetNick(), uLongIP, uPort, "", true, m_pUser, CUtils::GetIP(uLongIP));
|
||||
if (uBNCPort) {
|
||||
CString sIP = m_pUser->GetLocalDCCIP();
|
||||
m_pUser->PutUser(":" + Nick.GetNickMask() + " PRIVMSG " + GetNick() + " :\001DCC CHAT chat " + CString(CUtils::GetLongIP(sIP)) + " " + CString(uBNCPort) + "\001");
|
||||
}
|
||||
} else if (sType.Equals("SEND")) {
|
||||
// DCC SEND readme.txt 403120438 5550 1104
|
||||
unsigned short uBNCPort = CDCCBounce::DCCRequest(Nick.GetNick(), uLongIP, uPort, sFile, false, m_pUser, CUtils::GetIP(uLongIP));
|
||||
if (uBNCPort) {
|
||||
CString sIP = m_pUser->GetLocalDCCIP();
|
||||
m_pUser->PutUser(":" + Nick.GetNickMask() + " PRIVMSG " + GetNick() + " :\001DCC SEND " + sFile + " " + CString(CUtils::GetLongIP(sIP)) + " " + CString(uBNCPort) + " " + CString(uFileSize) + "\001");
|
||||
}
|
||||
} else if (sType.Equals("RESUME")) {
|
||||
// Need to lookup the connection by port, filter the port, and forward to the user
|
||||
CDCCBounce* pSock = (CDCCBounce*) CZNC::Get().GetManager().FindSockByLocalPort(sMessage.Token(3).ToUShort());
|
||||
|
||||
if (pSock && pSock->GetSockName().Equals("DCC::", false, 5)) {
|
||||
m_pUser->PutUser(":" + Nick.GetNickMask() + " PRIVMSG " + GetNick() + " :\001DCC " + sType + " " + sFile + " " + CString(pSock->GetUserPort()) + " " + sMessage.Token(4) + "\001");
|
||||
}
|
||||
} else if (sType.Equals("ACCEPT")) {
|
||||
// Need to lookup the connection by port, filter the port, and forward to the user
|
||||
CSockManager& Manager = CZNC::Get().GetManager();
|
||||
|
||||
for (unsigned int a = 0; a < Manager.size(); a++) {
|
||||
CDCCBounce* pSock = (CDCCBounce*) Manager[a];
|
||||
|
||||
if (pSock && pSock->GetSockName().Equals("DCC::", false, 5)) {
|
||||
if (pSock->GetUserPort() == sMessage.Token(3).ToUShort()) {
|
||||
m_pUser->PutUser(":" + Nick.GetNickMask() + " PRIVMSG " + GetNick() + " :\001DCC " + sType + " " + sFile + " " + CString(pSock->GetLocalPort()) + " " + sMessage.Token(4) + "\001");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// This handles everything which wasn't handled yet
|
||||
return OnGeneralCTCP(Nick, sMessage);
|
||||
}
|
||||
|
||||
+1
-1
@@ -28,7 +28,7 @@ INSTALL_PROGRAM := @INSTALL_PROGRAM@
|
||||
INSTALL_SCRIPT := @INSTALL_SCRIPT@
|
||||
INSTALL_DATA := @INSTALL_DATA@
|
||||
|
||||
LIB_SRCS := ZNCString.cpp Csocket.cpp znc.cpp User.cpp IRCSock.cpp Client.cpp DCCBounce.cpp \
|
||||
LIB_SRCS := ZNCString.cpp Csocket.cpp znc.cpp User.cpp IRCSock.cpp Client.cpp \
|
||||
DCCSock.cpp Chan.cpp Nick.cpp Server.cpp Modules.cpp MD5.cpp Buffer.cpp Utils.cpp \
|
||||
FileUtils.cpp HTTPSock.cpp Template.cpp ClientCommand.cpp Socket.cpp SHA256.cpp \
|
||||
WebModules.cpp Listener.cpp Config.cpp ZNCDebug.cpp
|
||||
|
||||
@@ -70,9 +70,7 @@ CUser::CUser(const CString& sUserName)
|
||||
m_MotdBuffer.SetLineCount(200); // This should be more than enough motd lines
|
||||
m_QueryBuffer.SetLineCount(250);
|
||||
m_bMultiClients = true;
|
||||
m_bBounceDCCs = true;
|
||||
m_eHashType = HASH_NONE;
|
||||
m_bUseClientIP = false;
|
||||
m_bDenyLoadMod = false;
|
||||
m_bAdmin= false;
|
||||
m_bIRCAway = false;
|
||||
@@ -105,8 +103,6 @@ CUser::~CUser() {
|
||||
|
||||
// This will cause an endless loop if the destructor doesn't remove the
|
||||
// socket from this list / if the socket doesn't exist any more.
|
||||
while (!m_sDCCBounces.empty())
|
||||
CZNC::Get().GetManager().DelSockByAddr((CZNCSock*) *m_sDCCBounces.begin());
|
||||
while (!m_sDCCSocks.empty())
|
||||
CZNC::Get().GetManager().DelSockByAddr((CZNCSock*) *m_sDCCSocks.begin());
|
||||
|
||||
@@ -143,7 +139,6 @@ bool CUser::ParseConfig(CConfig* pConfig, CString& sError) {
|
||||
TOption<bool> BoolOptions[] = {
|
||||
{ "keepbuffer", &CUser::SetKeepBuffer },
|
||||
{ "multiclients", &CUser::SetMultiClients },
|
||||
{ "bouncedccs", &CUser::SetBounceDCCs },
|
||||
{ "denyloadmod", &CUser::SetDenyLoadMod },
|
||||
{ "admin", &CUser::SetAdmin },
|
||||
{ "denysetbindhost", &CUser::SetDenySetBindHost },
|
||||
@@ -192,6 +187,26 @@ bool CUser::ParseConfig(CConfig* pConfig, CString& sError) {
|
||||
}
|
||||
|
||||
CString sValue;
|
||||
|
||||
CString sDCCLookupValue;
|
||||
pConfig->FindStringEntry("dcclookupmethod", sDCCLookupValue);
|
||||
if (pConfig->FindStringEntry("bouncedccs", sValue)) {
|
||||
if (sValue.ToBool()) {
|
||||
CUtils::PrintAction("Loading Module [bouncedcc]");
|
||||
CString sModRet;
|
||||
bool bModRet = GetModules().LoadModule("bouncedcc", "", this, sModRet);
|
||||
|
||||
CUtils::PrintStatus(bModRet, sModRet);
|
||||
if (!bModRet) {
|
||||
sError = sModRet;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (sDCCLookupValue.Equals("Client")) {
|
||||
GetModules().FindModule("bouncedcc")->SetNV("UseClientIP", "1");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (pConfig->FindStringEntry("buffer", sValue))
|
||||
SetBufferCount(sValue.ToUInt(), true);
|
||||
if (pConfig->FindStringEntry("awaysuffix", sValue)) {
|
||||
@@ -231,8 +246,6 @@ bool CUser::ParseConfig(CConfig* pConfig, CString& sError) {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (pConfig->FindStringEntry("dcclookupmethod", sValue))
|
||||
SetUseClientIP(sValue.Equals("Client"));
|
||||
pConfig->FindStringEntry("pass", sValue);
|
||||
// There are different formats for this available:
|
||||
// Pass = <plain text>
|
||||
@@ -664,8 +677,6 @@ bool CUser::Clone(const CUser& User, CString& sErrorRet, bool bCloneChans) {
|
||||
SetIRCConnectEnabled(User.GetIRCConnectEnabled());
|
||||
SetKeepBuffer(User.KeepBuffer());
|
||||
SetMultiClients(User.MultiClients());
|
||||
SetBounceDCCs(User.BounceDCCs());
|
||||
SetUseClientIP(User.UseClientIP());
|
||||
SetDenyLoadMod(User.DenyLoadMod());
|
||||
SetAdmin(User.IsAdmin());
|
||||
SetDenySetBindHost(User.DenySetBindHost());
|
||||
@@ -863,11 +874,9 @@ bool CUser::WriteConfig(CFile& File) {
|
||||
PrintLine(File, "Buffer", CString(GetBufferCount()));
|
||||
PrintLine(File, "KeepBuffer", CString(KeepBuffer()));
|
||||
PrintLine(File, "MultiClients", CString(MultiClients()));
|
||||
PrintLine(File, "BounceDCCs", CString(BounceDCCs()));
|
||||
PrintLine(File, "DenyLoadMod", CString(DenyLoadMod()));
|
||||
PrintLine(File, "Admin", CString(IsAdmin()));
|
||||
PrintLine(File, "DenySetBindHost", CString(DenySetBindHost()));
|
||||
PrintLine(File, "DCCLookupMethod", CString((UseClientIP()) ? "client" : "default"));
|
||||
PrintLine(File, "TimestampFormat", GetTimestampFormat());
|
||||
PrintLine(File, "AppendTimestamp", CString(GetTimestampAppend()));
|
||||
PrintLine(File, "PrependTimestamp", CString(GetTimestampPrepend()));
|
||||
@@ -1426,8 +1435,6 @@ void CUser::SetPass(const CString& s, eHashType eHash, const CString& sSalt) {
|
||||
m_sPassSalt = sSalt;
|
||||
}
|
||||
void CUser::SetMultiClients(bool b) { m_bMultiClients = b; }
|
||||
void CUser::SetBounceDCCs(bool b) { m_bBounceDCCs = b; }
|
||||
void CUser::SetUseClientIP(bool b) { m_bUseClientIP = b; }
|
||||
void CUser::SetDenyLoadMod(bool b) { m_bDenyLoadMod = b; }
|
||||
void CUser::SetAdmin(bool b) { m_bAdmin = b; }
|
||||
void CUser::SetDenySetBindHost(bool b) { m_bDenySetBindHost = b; }
|
||||
@@ -1497,12 +1504,10 @@ const CString& CUser::GetPass() const { return m_sPass; }
|
||||
CUser::eHashType CUser::GetPassHashType() const { return m_eHashType; }
|
||||
const CString& CUser::GetPassSalt() const { return m_sPassSalt; }
|
||||
|
||||
bool CUser::UseClientIP() const { return m_bUseClientIP; }
|
||||
bool CUser::DenyLoadMod() const { return m_bDenyLoadMod; }
|
||||
bool CUser::IsAdmin() const { return m_bAdmin; }
|
||||
bool CUser::DenySetBindHost() const { return m_bDenySetBindHost; }
|
||||
bool CUser::MultiClients() const { return m_bMultiClients; }
|
||||
bool CUser::BounceDCCs() const { return m_bBounceDCCs; }
|
||||
const CString& CUser::GetStatusPrefix() const { return m_sStatusPrefix; }
|
||||
const CString& CUser::GetDefaultChanModes() const { return m_sDefaultChanModes; }
|
||||
const vector<CChan*>& CUser::GetChans() const { return m_vChans; }
|
||||
|
||||
@@ -26,7 +26,6 @@ class CFile;
|
||||
class CIRCSock;
|
||||
class CUserTimer;
|
||||
class CServer;
|
||||
class CDCCBounce;
|
||||
class CDCCSock;
|
||||
|
||||
class CUser {
|
||||
@@ -117,8 +116,6 @@ public:
|
||||
void IRCDisconnected();
|
||||
void CheckIRCConnect();
|
||||
|
||||
void AddDCCBounce(CDCCBounce* p) { m_sDCCBounces.insert(p); }
|
||||
void DelDCCBounce(CDCCBounce* p) { m_sDCCBounces.erase(p); }
|
||||
void AddDCCSock(CDCCSock* p) { m_sDCCSocks.insert(p); }
|
||||
void DelDCCSock(CDCCSock* p) { m_sDCCSocks.erase(p); }
|
||||
|
||||
@@ -146,9 +143,7 @@ public:
|
||||
void SetBindHost(const CString& s);
|
||||
void SetDCCBindHost(const CString& s);
|
||||
void SetPass(const CString& s, eHashType eHash, const CString& sSalt = "");
|
||||
void SetBounceDCCs(bool b);
|
||||
void SetMultiClients(bool b);
|
||||
void SetUseClientIP(bool b);
|
||||
void SetDenyLoadMod(bool b);
|
||||
void SetAdmin(bool b);
|
||||
void SetDenySetBindHost(bool b);
|
||||
@@ -201,11 +196,9 @@ public:
|
||||
const CString& GetUserPath() const;
|
||||
const CString& GetDLPath() const;
|
||||
|
||||
bool UseClientIP() const;
|
||||
bool DenyLoadMod() const;
|
||||
bool IsAdmin() const;
|
||||
bool DenySetBindHost() const;
|
||||
bool BounceDCCs() const;
|
||||
bool MultiClients() const;
|
||||
const CString& GetStatusPrefix() const;
|
||||
const CString& GetDefaultChanModes() const;
|
||||
@@ -263,8 +256,6 @@ protected:
|
||||
CBuffer m_MotdBuffer;
|
||||
CBuffer m_QueryBuffer;
|
||||
bool m_bMultiClients;
|
||||
bool m_bBounceDCCs;
|
||||
bool m_bUseClientIP;
|
||||
bool m_bDenyLoadMod;
|
||||
bool m_bAdmin;
|
||||
bool m_bDenySetBindHost;
|
||||
@@ -280,7 +271,6 @@ protected:
|
||||
vector<CServer*> m_vServers;
|
||||
vector<CChan*> m_vChans;
|
||||
vector<CClient*> m_vClients;
|
||||
set<CDCCBounce*> m_sDCCBounces;
|
||||
set<CDCCSock*> m_sDCCSocks;
|
||||
set<CString> m_ssAllowedHosts;
|
||||
unsigned int m_uServerIdx; ///< Index in m_vServers of our current server + 1
|
||||
|
||||
@@ -49,8 +49,6 @@ class CAdminMod : public CModule {
|
||||
{"RealName", str},
|
||||
{"BindHost", str},
|
||||
{"MultiClients", boolean},
|
||||
{"BounceDCCs", boolean},
|
||||
{"UseClientIP", boolean},
|
||||
{"DenyLoadMod", boolean},
|
||||
{"DenySetBindHost", boolean},
|
||||
{"DefaultChanModes", str},
|
||||
@@ -143,10 +141,6 @@ class CAdminMod : public CModule {
|
||||
PutModule("BindHost = " + pUser->GetBindHost());
|
||||
else if (sVar == "multiclients")
|
||||
PutModule("MultiClients = " + CString(pUser->MultiClients()));
|
||||
else if (sVar == "bouncedccs")
|
||||
PutModule("BounceDCCs = " + CString(pUser->BounceDCCs()));
|
||||
else if (sVar == "useclientip")
|
||||
PutModule("UseClientIP = " + CString(pUser->UseClientIP()));
|
||||
else if (sVar == "denyloadmod")
|
||||
PutModule("DenyLoadMod = " + CString(pUser->DenyLoadMod()));
|
||||
else if (sVar == "denysetbindhost")
|
||||
@@ -224,16 +218,6 @@ class CAdminMod : public CModule {
|
||||
pUser->SetMultiClients(b);
|
||||
PutModule("MultiClients = " + CString(b));
|
||||
}
|
||||
else if (sVar == "bouncedccs") {
|
||||
bool b = sValue.ToBool();
|
||||
pUser->SetBounceDCCs(b);
|
||||
PutModule("BounceDCCs = " + CString(b));
|
||||
}
|
||||
else if (sVar == "useclientip") {
|
||||
bool b = sValue.ToBool();
|
||||
pUser->SetUseClientIP(b);
|
||||
PutModule("UseClientIP = " + CString(b));
|
||||
}
|
||||
else if (sVar == "denyloadmod") {
|
||||
if(m_pUser->IsAdmin()) {
|
||||
bool b = sValue.ToBool();
|
||||
|
||||
@@ -0,0 +1,455 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2011 See the AUTHORS file for details.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 as published
|
||||
* by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include "zncconfig.h"
|
||||
#include "znc.h"
|
||||
#include "User.h"
|
||||
#include "Modules.h"
|
||||
#include "Socket.h"
|
||||
#include "FileUtils.h"
|
||||
|
||||
class CBounceDCCMod;
|
||||
|
||||
class CDCCBounce : public CSocket {
|
||||
public:
|
||||
CDCCBounce(CBounceDCCMod* pMod, unsigned long uLongIP, unsigned short uPort,
|
||||
const CString& sFileName, const CString& sRemoteNick,
|
||||
const CString& sRemoteIP, bool bIsChat = false);
|
||||
CDCCBounce(CBounceDCCMod* pMod, const CString& sHostname, unsigned short uPort,
|
||||
const CString& sRemoteNick, const CString& sRemoteIP,
|
||||
const CString& sFileName, int iTimeout = 60, bool bIsChat = false);
|
||||
virtual ~CDCCBounce();
|
||||
|
||||
static unsigned short DCCRequest(const CString& sNick, unsigned long uLongIP, unsigned short uPort, const CString& sFileName, bool bIsChat, CBounceDCCMod* pMod, const CString& sRemoteIP);
|
||||
|
||||
void ReadLine(const CString& sData);
|
||||
virtual void ReadData(const char* data, size_t len);
|
||||
virtual void ReadPaused();
|
||||
virtual void Timeout();
|
||||
virtual void ConnectionRefused();
|
||||
virtual void ReachedMaxBuffer();
|
||||
virtual void SockError(int iErrno);
|
||||
virtual void Connected();
|
||||
virtual void Disconnected();
|
||||
virtual Csock* GetSockObj(const CString& sHost, unsigned short uPort);
|
||||
void Shutdown();
|
||||
void PutServ(const CString& sLine);
|
||||
void PutPeer(const CString& sLine);
|
||||
bool IsPeerConnected() { return (m_pPeer) ? m_pPeer->IsConnected() : false; }
|
||||
|
||||
// Setters
|
||||
void SetPeer(CDCCBounce* p) { m_pPeer = p; }
|
||||
void SetRemoteIP(const CString& s) { m_sRemoteIP = s; }
|
||||
void SetRemoteNick(const CString& s) { m_sRemoteNick = s; }
|
||||
void SetRemote(bool b) { m_bIsRemote = b; }
|
||||
// !Setters
|
||||
|
||||
// Getters
|
||||
unsigned short GetUserPort() const { return m_uRemotePort; }
|
||||
const CString& GetRemoteIP() const { return m_sRemoteIP; }
|
||||
const CString& GetRemoteNick() const { return m_sRemoteNick; }
|
||||
const CString& GetFileName() const { return m_sFileName; }
|
||||
CDCCBounce* GetPeer() const { return m_pPeer; }
|
||||
bool IsRemote() { return m_bIsRemote; }
|
||||
bool IsChat() { return m_bIsChat; }
|
||||
// !Getters
|
||||
private:
|
||||
protected:
|
||||
CString m_sRemoteNick;
|
||||
CString m_sRemoteIP;
|
||||
CString m_sConnectIP;
|
||||
CString m_sLocalIP;
|
||||
CString m_sFileName;
|
||||
CBounceDCCMod* m_pModule;
|
||||
CDCCBounce* m_pPeer;
|
||||
unsigned short m_uRemotePort;
|
||||
bool m_bIsChat;
|
||||
bool m_bIsRemote;
|
||||
|
||||
static const unsigned int m_uiMaxDCCBuffer;
|
||||
static const unsigned int m_uiMinDCCBuffer;
|
||||
};
|
||||
|
||||
// If we buffer more than this in memory, we will throttle the receiving side
|
||||
const unsigned int CDCCBounce::m_uiMaxDCCBuffer = 10 * 1024;
|
||||
// If less than this is in the buffer, the receiving side continues
|
||||
const unsigned int CDCCBounce::m_uiMinDCCBuffer = 2 * 1024;
|
||||
|
||||
class CBounceDCCMod : public CModule {
|
||||
public:
|
||||
void ListDCCsCommand(const CString& sLine) {
|
||||
CTable Table;
|
||||
Table.AddColumn("Type");
|
||||
Table.AddColumn("State");
|
||||
Table.AddColumn("Speed");
|
||||
Table.AddColumn("Nick");
|
||||
Table.AddColumn("IP");
|
||||
Table.AddColumn("File");
|
||||
|
||||
set<CSocket*>::const_iterator it;
|
||||
for (it = BeginSockets(); it != EndSockets(); ++it) {
|
||||
CDCCBounce* pSock = (CDCCBounce*) *it;
|
||||
CString sSockName = pSock->GetSockName();
|
||||
|
||||
if (!(pSock->IsRemote())) {
|
||||
Table.AddRow();
|
||||
Table.SetCell("Nick", pSock->GetRemoteNick());
|
||||
Table.SetCell("IP", pSock->GetRemoteIP());
|
||||
|
||||
if (pSock->IsChat()) {
|
||||
Table.SetCell("Type", "Chat");
|
||||
} else {
|
||||
Table.SetCell("Type", "Xfer");
|
||||
Table.SetCell("File", pSock->GetFileName());
|
||||
}
|
||||
|
||||
CString sState = "Waiting";
|
||||
if ((pSock->IsConnected()) || (pSock->IsPeerConnected())) {
|
||||
sState = "Halfway";
|
||||
if ((pSock->IsPeerConnected()) && (pSock->IsPeerConnected())) {
|
||||
sState = "Connected";
|
||||
}
|
||||
}
|
||||
Table.SetCell("State", sState);
|
||||
}
|
||||
}
|
||||
|
||||
if (PutModule(Table) == 0) {
|
||||
PutModule("You have no active DCCs.");
|
||||
}
|
||||
}
|
||||
|
||||
void UseClientIPCommand(const CString& sLine) {
|
||||
CString sValue = sLine.Token(1, true);
|
||||
|
||||
if (!sValue.empty()) {
|
||||
SetNV("UseClientIP", sValue);
|
||||
}
|
||||
|
||||
PutModule("UseClientIP: " + CString(GetNV("UseClientIP").ToBool()));
|
||||
}
|
||||
|
||||
MODCONSTRUCTOR(CBounceDCCMod) {
|
||||
AddHelpCommand();
|
||||
AddCommand("ListDCCs", static_cast<CModCommand::ModCmdFunc>(&CBounceDCCMod::ListDCCsCommand),
|
||||
"", "List all active DCCs");
|
||||
AddCommand("UseClientIP", static_cast<CModCommand::ModCmdFunc>(&CBounceDCCMod::UseClientIPCommand),
|
||||
"<true|false>");
|
||||
}
|
||||
|
||||
virtual ~CBounceDCCMod() {}
|
||||
|
||||
CString GetLocalDCCIP() {
|
||||
return m_pUser->GetLocalDCCIP();
|
||||
}
|
||||
|
||||
bool UseClientIP() {
|
||||
return GetNV("UseClientIP").ToBool();
|
||||
}
|
||||
|
||||
virtual EModRet OnUserCTCP(CString& sTarget, CString& sMessage) {
|
||||
if (sMessage.Equals("DCC ", false, 4)) {
|
||||
CString sType = sMessage.Token(1);
|
||||
CString sFile = sMessage.Token(2);
|
||||
unsigned long uLongIP = sMessage.Token(3).ToULong();
|
||||
unsigned short uPort = sMessage.Token(4).ToUShort();
|
||||
unsigned long uFileSize = sMessage.Token(5).ToULong();
|
||||
CString sIP = GetLocalDCCIP();
|
||||
|
||||
if (!UseClientIP()) {
|
||||
uLongIP = CUtils::GetLongIP(m_pClient->GetRemoteIP());
|
||||
}
|
||||
|
||||
if (sType.Equals("CHAT")) {
|
||||
unsigned short uBNCPort = CDCCBounce::DCCRequest(sTarget, uLongIP, uPort, "", true, this, "");
|
||||
if (uBNCPort) {
|
||||
PutIRC("PRIVMSG " + sTarget + " :\001DCC CHAT chat " + CString(CUtils::GetLongIP(sIP)) + " " + CString(uBNCPort) + "\001");
|
||||
}
|
||||
} else if (sType.Equals("SEND")) {
|
||||
// DCC SEND readme.txt 403120438 5550 1104
|
||||
unsigned short uBNCPort = CDCCBounce::DCCRequest(sTarget, uLongIP, uPort, sFile, false, this, "");
|
||||
if (uBNCPort) {
|
||||
PutIRC("PRIVMSG " + sTarget + " :\001DCC SEND " + sFile + " " + CString(CUtils::GetLongIP(sIP)) + " " + CString(uBNCPort) + " " + CString(uFileSize) + "\001");
|
||||
}
|
||||
} else if (sType.Equals("RESUME")) {
|
||||
// PRIVMSG user :DCC RESUME "znc.o" 58810 151552
|
||||
unsigned short uResumePort = sMessage.Token(3).ToUShort();
|
||||
|
||||
set<CSocket*>::const_iterator it;
|
||||
for (it = BeginSockets(); it != EndSockets(); ++it) {
|
||||
CDCCBounce* pSock = (CDCCBounce*) *it;
|
||||
|
||||
if (pSock->GetLocalPort() == uResumePort) {
|
||||
PutIRC("PRIVMSG " + sTarget + " :\001DCC " + sType + " " + sFile + " " + CString(pSock->GetUserPort()) + " " + sMessage.Token(4) + "\001");
|
||||
}
|
||||
}
|
||||
} else if (sType.Equals("ACCEPT")) {
|
||||
// Need to lookup the connection by port, filter the port, and forward to the user
|
||||
|
||||
set<CSocket*>::const_iterator it;
|
||||
for (it = BeginSockets(); it != EndSockets(); ++it) {
|
||||
CDCCBounce* pSock = (CDCCBounce*) *it;
|
||||
if (pSock->GetUserPort() == sMessage.Token(3).ToUShort()) {
|
||||
PutIRC("PRIVMSG " + sTarget + " :\001DCC " + sType + " " + sFile + " " + CString(pSock->GetLocalPort()) + " " + sMessage.Token(4) + "\001");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return HALTCORE;
|
||||
}
|
||||
|
||||
return CONTINUE;
|
||||
}
|
||||
|
||||
virtual EModRet OnPrivCTCP(CNick& Nick, CString& sMessage) {
|
||||
if (sMessage.Equals("DCC ", false, 4) && m_pUser->IsUserAttached()) {
|
||||
// DCC CHAT chat 2453612361 44592
|
||||
CString sType = sMessage.Token(1);
|
||||
CString sFile = sMessage.Token(2);
|
||||
unsigned long uLongIP = sMessage.Token(3).ToULong();
|
||||
unsigned short uPort = sMessage.Token(4).ToUShort();
|
||||
unsigned long uFileSize = sMessage.Token(5).ToULong();
|
||||
|
||||
if (sType.Equals("CHAT")) {
|
||||
CNick FromNick(Nick.GetNickMask());
|
||||
unsigned short uBNCPort = CDCCBounce::DCCRequest(FromNick.GetNick(), uLongIP, uPort, "", true, this, CUtils::GetIP(uLongIP));
|
||||
if (uBNCPort) {
|
||||
CString sIP = GetLocalDCCIP();
|
||||
m_pUser->PutUser(":" + Nick.GetNickMask() + " PRIVMSG " + m_pUser->GetNick() + " :\001DCC CHAT chat " + CString(CUtils::GetLongIP(sIP)) + " " + CString(uBNCPort) + "\001");
|
||||
}
|
||||
} else if (sType.Equals("SEND")) {
|
||||
// DCC SEND readme.txt 403120438 5550 1104
|
||||
unsigned short uBNCPort = CDCCBounce::DCCRequest(Nick.GetNick(), uLongIP, uPort, sFile, false, this, CUtils::GetIP(uLongIP));
|
||||
if (uBNCPort) {
|
||||
CString sIP = GetLocalDCCIP();
|
||||
m_pUser->PutUser(":" + Nick.GetNickMask() + " PRIVMSG " + m_pUser->GetNick() + " :\001DCC SEND " + sFile + " " + CString(CUtils::GetLongIP(sIP)) + " " + CString(uBNCPort) + " " + CString(uFileSize) + "\001");
|
||||
}
|
||||
} else if (sType.Equals("RESUME")) {
|
||||
// Need to lookup the connection by port, filter the port, and forward to the user
|
||||
unsigned short uResumePort = sMessage.Token(3).ToUShort();
|
||||
|
||||
set<CSocket*>::const_iterator it;
|
||||
for (it = BeginSockets(); it != EndSockets(); ++it) {
|
||||
CDCCBounce* pSock = (CDCCBounce*) *it;
|
||||
|
||||
if (pSock->GetLocalPort() == uResumePort) {
|
||||
m_pUser->PutUser(":" + Nick.GetNickMask() + " PRIVMSG " + m_pClient->GetNick() + " :\001DCC " + sType + " " + sFile + " " + CString(pSock->GetUserPort()) + " " + sMessage.Token(4) + "\001");
|
||||
}
|
||||
}
|
||||
} else if (sType.Equals("ACCEPT")) {
|
||||
// Need to lookup the connection by port, filter the port, and forward to the user
|
||||
set<CSocket*>::const_iterator it;
|
||||
for (it = BeginSockets(); it != EndSockets(); ++it) {
|
||||
CDCCBounce* pSock = (CDCCBounce*) *it;
|
||||
|
||||
if (pSock->GetUserPort() == sMessage.Token(3).ToUShort()) {
|
||||
m_pUser->PutUser(":" + Nick.GetNickMask() + " PRIVMSG " + m_pClient->GetNick() + " :\001DCC " + sType + " " + sFile + " " + CString(pSock->GetLocalPort()) + " " + sMessage.Token(4) + "\001");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return HALTCORE;
|
||||
}
|
||||
|
||||
return CONTINUE;
|
||||
}
|
||||
};
|
||||
|
||||
CDCCBounce::CDCCBounce(CBounceDCCMod* pMod, unsigned long uLongIP, unsigned short uPort,
|
||||
const CString& sFileName, const CString& sRemoteNick,
|
||||
const CString& sRemoteIP, bool bIsChat) : CSocket(pMod) {
|
||||
m_uRemotePort = uPort;
|
||||
m_sConnectIP = CUtils::GetIP(uLongIP);
|
||||
m_sRemoteIP = sRemoteIP;
|
||||
m_sFileName = sFileName;
|
||||
m_sRemoteNick = sRemoteNick;
|
||||
m_pModule = pMod;
|
||||
m_bIsChat = bIsChat;
|
||||
m_sLocalIP = pMod->GetLocalDCCIP();
|
||||
m_pPeer = NULL;
|
||||
m_bIsRemote = false;
|
||||
|
||||
if (bIsChat) {
|
||||
EnableReadLine();
|
||||
} else {
|
||||
DisableReadLine();
|
||||
}
|
||||
}
|
||||
|
||||
CDCCBounce::CDCCBounce(CBounceDCCMod* pMod, const CString& sHostname, unsigned short uPort,
|
||||
const CString& sRemoteNick, const CString& sRemoteIP, const CString& sFileName,
|
||||
int iTimeout, bool bIsChat) : CSocket(pMod, sHostname, uPort, iTimeout) {
|
||||
m_uRemotePort = 0;
|
||||
m_bIsChat = bIsChat;
|
||||
m_pModule = pMod;
|
||||
m_pPeer = NULL;
|
||||
m_sRemoteNick = sRemoteNick;
|
||||
m_sFileName = sFileName;
|
||||
m_sRemoteIP = sRemoteIP;
|
||||
m_bIsRemote = false;
|
||||
|
||||
SetMaxBufferThreshold(10240);
|
||||
if (bIsChat) {
|
||||
EnableReadLine();
|
||||
} else {
|
||||
DisableReadLine();
|
||||
}
|
||||
}
|
||||
|
||||
CDCCBounce::~CDCCBounce() {
|
||||
if (m_pPeer) {
|
||||
m_pPeer->Shutdown();
|
||||
m_pPeer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void CDCCBounce::ReadLine(const CString& sData) {
|
||||
CString sLine = sData.TrimRight_n("\r\n");
|
||||
|
||||
DEBUG(GetSockName() << " <- [" << sLine << "]");
|
||||
|
||||
PutPeer(sLine);
|
||||
}
|
||||
|
||||
void CDCCBounce::ReachedMaxBuffer() {
|
||||
DEBUG(GetSockName() << " == ReachedMaxBuffer()");
|
||||
|
||||
CString sType = (m_bIsChat) ? "Chat" : "Xfer";
|
||||
|
||||
m_pModule->PutModule("DCC " + sType + " Bounce (" + m_sRemoteNick + "): Too long line received");
|
||||
Close();
|
||||
}
|
||||
|
||||
void CDCCBounce::ReadData(const char* data, size_t len) {
|
||||
if (m_pPeer) {
|
||||
m_pPeer->Write(data, len);
|
||||
|
||||
size_t BufLen = m_pPeer->GetInternalWriteBuffer().length();
|
||||
|
||||
if (BufLen >= m_uiMaxDCCBuffer) {
|
||||
DEBUG(GetSockName() << " The send buffer is over the "
|
||||
"limit (" << BufLen <<"), throttling");
|
||||
PauseRead();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CDCCBounce::ReadPaused() {
|
||||
if (!m_pPeer || m_pPeer->GetInternalWriteBuffer().length() <= m_uiMinDCCBuffer)
|
||||
UnPauseRead();
|
||||
}
|
||||
|
||||
void CDCCBounce::Timeout() {
|
||||
DEBUG(GetSockName() << " == Timeout()");
|
||||
CString sType = (m_bIsChat) ? "Chat" : "Xfer";
|
||||
|
||||
if (IsRemote()) {
|
||||
CString sHost = Csock::GetHostName();
|
||||
if (!sHost.empty()) {
|
||||
sHost = " to [" + sHost + " " + CString(Csock::GetPort()) + "]";
|
||||
} else {
|
||||
sHost = ".";
|
||||
}
|
||||
|
||||
m_pModule->PutModule("DCC " + sType + " Bounce (" + m_sRemoteNick + "): Timeout while connecting" + sHost);
|
||||
} else {
|
||||
m_pModule->PutModule("DCC " + sType + " Bounce (" + m_sRemoteNick + "): Timeout waiting for incoming connection [" + Csock::GetLocalIP() + ":" + CString(Csock::GetLocalPort()) + "]");
|
||||
}
|
||||
}
|
||||
|
||||
void CDCCBounce::ConnectionRefused() {
|
||||
DEBUG(GetSockName() << " == ConnectionRefused()");
|
||||
|
||||
CString sType = (m_bIsChat) ? "Chat" : "Xfer";
|
||||
CString sHost = Csock::GetHostName();
|
||||
if (!sHost.empty()) {
|
||||
sHost = " to [" + sHost + " " + CString(Csock::GetPort()) + "]";
|
||||
} else {
|
||||
sHost = ".";
|
||||
}
|
||||
|
||||
m_pModule->PutModule("DCC " + sType + " Bounce (" + m_sRemoteNick + "): Connection Refused while connecting" + sHost);
|
||||
}
|
||||
|
||||
void CDCCBounce::SockError(int iErrno) {
|
||||
DEBUG(GetSockName() << " == SockError(" << iErrno << ")");
|
||||
CString sType = (m_bIsChat) ? "Chat" : "Xfer";
|
||||
|
||||
if (IsRemote()) {
|
||||
CString sHost = Csock::GetHostName();
|
||||
if (!sHost.empty()) {
|
||||
sHost = "[" + sHost + " " + CString(Csock::GetPort()) + "]";
|
||||
}
|
||||
|
||||
m_pModule->PutModule("DCC " + sType + " Bounce (" + m_sRemoteNick + "): Socket error [" + CString(strerror(iErrno)) + "]" + sHost);
|
||||
} else {
|
||||
m_pModule->PutModule("DCC " + sType + " Bounce (" + m_sRemoteNick + "): Socket error [" + CString(strerror(iErrno)) + "] [" + Csock::GetLocalIP() + ":" + CString(Csock::GetLocalPort()) + "]");
|
||||
}
|
||||
}
|
||||
|
||||
void CDCCBounce::Connected() {
|
||||
DEBUG(GetSockName() << " == Connected()");
|
||||
}
|
||||
|
||||
void CDCCBounce::Disconnected() {
|
||||
DEBUG(GetSockName() << " == Disconnected()");
|
||||
}
|
||||
|
||||
void CDCCBounce::Shutdown() {
|
||||
m_pPeer = NULL;
|
||||
DEBUG(GetSockName() << " == Close(); because my peer told me to");
|
||||
Close();
|
||||
}
|
||||
|
||||
Csock* CDCCBounce::GetSockObj(const CString& sHost, unsigned short uPort) {
|
||||
Close();
|
||||
|
||||
if (m_sRemoteIP.empty()) {
|
||||
m_sRemoteIP = sHost;
|
||||
}
|
||||
|
||||
CDCCBounce* pSock = new CDCCBounce(m_pModule, sHost, uPort, m_sRemoteNick, m_sRemoteIP, m_sFileName, m_bIsChat);
|
||||
CDCCBounce* pRemoteSock = new CDCCBounce(m_pModule, sHost, uPort, m_sRemoteNick, m_sRemoteIP, m_sFileName, m_bIsChat);
|
||||
pSock->SetPeer(pRemoteSock);
|
||||
pRemoteSock->SetPeer(pSock);
|
||||
pRemoteSock->SetRemote(true);
|
||||
pSock->SetRemote(false);
|
||||
|
||||
if (!CZNC::Get().GetManager().Connect(m_sConnectIP, m_uRemotePort, "DCC::" + CString((m_bIsChat) ? "Chat" : "XFER") + "::Remote::" + m_sRemoteNick, 60, false, m_sLocalIP, pRemoteSock)) {
|
||||
pRemoteSock->Close();
|
||||
}
|
||||
|
||||
pSock->SetSockName(GetSockName());
|
||||
return pSock;
|
||||
}
|
||||
|
||||
void CDCCBounce::PutServ(const CString& sLine) {
|
||||
DEBUG(GetSockName() << " -> [" << sLine << "]");
|
||||
Write(sLine + "\r\n");
|
||||
}
|
||||
|
||||
void CDCCBounce::PutPeer(const CString& sLine) {
|
||||
if (m_pPeer) {
|
||||
m_pPeer->PutServ(sLine);
|
||||
} else {
|
||||
PutServ("*** Not connected yet ***");
|
||||
}
|
||||
}
|
||||
|
||||
unsigned short CDCCBounce::DCCRequest(const CString& sNick, unsigned long uLongIP, unsigned short uPort, const CString& sFileName, bool bIsChat, CBounceDCCMod* pMod, const CString& sRemoteIP) {
|
||||
CDCCBounce* pDCCBounce = new CDCCBounce(pMod, uLongIP, uPort, sFileName, sNick, sRemoteIP, bIsChat);
|
||||
unsigned short uListenPort = CZNC::Get().GetManager().ListenRand("DCC::" + CString((bIsChat) ? "Chat" : "Xfer") + "::Local::" + sNick,
|
||||
pMod->GetLocalDCCIP(), false, SOMAXCONN, pDCCBounce, 120);
|
||||
|
||||
return uListenPort;
|
||||
}
|
||||
|
||||
|
||||
|
||||
MODULEDEFS(CBounceDCCMod, "Bounce DCC module")
|
||||
|
||||
@@ -29,7 +29,6 @@
|
||||
#include "../znc.h"
|
||||
#include "../Server.h"
|
||||
#include "../ZNCString.h"
|
||||
#include "../DCCBounce.h"
|
||||
#include "../DCCSock.h"
|
||||
#include "../FileUtils.h"
|
||||
#include "../ZNCDebug.h"
|
||||
@@ -79,7 +78,6 @@ namespace std {
|
||||
%include "../Csocket.h"
|
||||
%template(ZNCSocketManager) TSocketManager<CZNCSock>;
|
||||
%include "../Socket.h"
|
||||
%include "../DCCBounce.h"
|
||||
%include "../DCCSock.h"
|
||||
%include "../FileUtils.h"
|
||||
%include "../Modules.h"
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
#include "../znc.h"
|
||||
#include "../Server.h"
|
||||
#include "../ZNCString.h"
|
||||
#include "../DCCBounce.h"
|
||||
#include "../DCCSock.h"
|
||||
#include "../FileUtils.h"
|
||||
#include "../ZNCDebug.h"
|
||||
@@ -83,7 +82,6 @@ namespace std {
|
||||
%include "../Csocket.h"
|
||||
%template(ZNCSocketManager) TSocketManager<CZNCSock>;
|
||||
%include "../Socket.h"
|
||||
%include "../DCCBounce.h"
|
||||
%include "../DCCSock.h"
|
||||
%include "../FileUtils.h"
|
||||
%include "../Modules.h"
|
||||
|
||||
@@ -249,8 +249,6 @@ public:
|
||||
pNewUser->SetSkinName(WebSock.GetParam("skin"));
|
||||
pNewUser->SetKeepBuffer(WebSock.GetParam("keepbuffer").ToBool());
|
||||
pNewUser->SetMultiClients(WebSock.GetParam("multiclients").ToBool());
|
||||
pNewUser->SetBounceDCCs(WebSock.GetParam("bouncedccs").ToBool());
|
||||
pNewUser->SetUseClientIP(WebSock.GetParam("useclientip").ToBool());
|
||||
pNewUser->SetTimestampAppend(WebSock.GetParam("appendtimestamp").ToBool());
|
||||
pNewUser->SetTimestampPrepend(WebSock.GetParam("prependtimestamp").ToBool());
|
||||
pNewUser->SetTimezoneOffset(WebSock.GetParam("timezoneoffset").ToDouble());
|
||||
@@ -769,16 +767,6 @@ public:
|
||||
o4["DisplayName"] = "Multi Clients";
|
||||
if (!pUser || pUser->MultiClients()) { o4["Checked"] = "true"; }
|
||||
|
||||
CTemplate& o5 = Tmpl.AddRow("OptionLoop");
|
||||
o5["Name"] = "bouncedccs";
|
||||
o5["DisplayName"] = "Bounce DCCs";
|
||||
if (!pUser || pUser->BounceDCCs()) { o5["Checked"] = "true"; }
|
||||
|
||||
CTemplate& o6 = Tmpl.AddRow("OptionLoop");
|
||||
o6["Name"] = "useclientip";
|
||||
o6["DisplayName"] = "Use Client IP";
|
||||
if (pUser && pUser->UseClientIP()) { o6["Checked"] = "true"; }
|
||||
|
||||
CTemplate& o7 = Tmpl.AddRow("OptionLoop");
|
||||
o7["Name"] = "appendtimestamp";
|
||||
o7["DisplayName"] = "Append Timestamps";
|
||||
|
||||
Reference in New Issue
Block a user