aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar TheReign2015-12-07 12:41:49 -0500
committerGravatar TheReign2015-12-07 12:41:49 -0500
commit3734f3c4129429668dacd016759edec932d975fb (patch)
treedfdb18bb008d3e240c2c5471e09a437f812b1eb3
parentmkcreateinstanceproc: update capitalization in boileralte header in generator (diff)
downloadKVIrc-3734f3c4129429668dacd016759edec932d975fb.tar.gz
KVIrc-3734f3c4129429668dacd016759edec932d975fb.tar.bz2
KVIrc-3734f3c4129429668dacd016759edec932d975fb.zip
Added 64-bit ack option to DCC receive.
-rw-r--r--src/kvirc/kernel/KviOptions.cpp3
-rw-r--r--src/kvirc/kernel/KviOptions.h3
-rw-r--r--src/modules/dcc/DccFileTransfer.cpp60
-rw-r--r--src/modules/dcc/DccFileTransfer.h21
-rw-r--r--src/modules/options/OptionsWidget_dcc.cpp5
5 files changed, 47 insertions, 45 deletions
diff --git a/src/kvirc/kernel/KviOptions.cpp b/src/kvirc/kernel/KviOptions.cpp
index 0c71f7a7b..d9064be43 100644
--- a/src/kvirc/kernel/KviOptions.cpp
+++ b/src/kvirc/kernel/KviOptions.cpp
@@ -340,7 +340,8 @@ KviBoolOption g_boolOptionsTable[KVI_NUM_BOOL_OPTIONS]=
BOOL_OPTION("ShowUserFlagForChannelsInWindowList",true,KviOption_sectFlagWindowList | KviOption_resetUpdateGui),
BOOL_OPTION("EnableCustomCursorWidth",false,KviOption_sectFlagGui | KviOption_resetUpdateGui),
BOOL_OPTION("ShowFavoriteServersOnly",false,KviOption_sectFlagFrame),
- BOOL_OPTION("RequireControlToCopy",false,KviOption_sectFlagIrcView)
+ BOOL_OPTION("RequireControlToCopy",false,KviOption_sectFlagIrcView),
+ BOOL_OPTION("Send64BitAckInDccRecv",false,KviOption_sectFlagDcc)
};
#define STRING_OPTION(_txt,_val,_flags) KviStringOption(KVI_STRING_OPTIONS_PREFIX _txt,_val,_flags)
diff --git a/src/kvirc/kernel/KviOptions.h b/src/kvirc/kernel/KviOptions.h
index f230df05a..ab72e60b3 100644
--- a/src/kvirc/kernel/KviOptions.h
+++ b/src/kvirc/kernel/KviOptions.h
@@ -356,8 +356,9 @@ DECLARE_OPTION_STRUCT(KviStringListOption,QStringList)
#define KviOption_boolEnableCustomCursorWidth 261 /* interface */
#define KviOption_boolShowFavoriteServersOnly 262 /* connection::ircservers */
#define KviOption_boolRequireControlToCopy 263 /* interface::ircview */
+#define KviOption_boolSend64BitAckInDccRecv 264 /* dcc::send */
-#define KVI_NUM_BOOL_OPTIONS 264
+#define KVI_NUM_BOOL_OPTIONS 265
#define KVI_STRING_OPTIONS_PREFIX "string"
diff --git a/src/modules/dcc/DccFileTransfer.cpp b/src/modules/dcc/DccFileTransfer.cpp
index d404f85a7..536c8d7cd 100644
--- a/src/modules/dcc/DccFileTransfer.cpp
+++ b/src/modules/dcc/DccFileTransfer.cpp
@@ -68,6 +68,7 @@
#include <QEvent>
#include <QCloseEvent>
#include <QTimer>
+#include <QtEndian>
#define INSTANT_BANDWIDTH_CHECK_INTERVAL_IN_MSECS 3000
#define INSTANT_BANDWIDTH_CHECK_INTERVAL_IN_SECS 3
@@ -112,22 +113,29 @@ DccRecvThread::~DccRecvThread()
delete m_pTimeInterval;
}
-bool DccRecvThread::sendAck(int filePos,bool bTolerateErrors)
+bool DccRecvThread::sendAck(qint64 filePos, bool bUse64BitAck)
{
- quint32 size = htonl(filePos & 0xffffffff);
+ quint32 ack32 = htonl(filePos & 0xffffffff);
+ quint64 ack64 = qToBigEndian(filePos);
+
+ char * ack = (char*) &ack32;
+ int ackSize = 4;
+
+ if(bUse64BitAck)
+ {
+ ackSize = 8;
+ ack = (char*) &ack64;
+ }
+
int iRet=0;
#ifdef COMPILE_SSL_SUPPORT
if(m_pSSL)
- {
- iRet = m_pSSL->write((char*)(&size),4);
- } else {
-#endif //COMPILE_SSL_SUPPORT
- iRet = kvi_socket_send(m_fd,(void *)(&size),4);
-#ifdef COMPILE_SSL_SUPPORT
- }
+ iRet = m_pSSL->write(ack,ackSize);
+ else
#endif //COMPILE_SSL_SUPPORT
+ iRet = kvi_socket_send(m_fd,(void *)(ack),ackSize);
- if(iRet == 4)
+ if(iRet == ackSize)
return true; // everything sent
// When downloading from a fast server using send-ahead via an asymmetric link (such as the
@@ -147,9 +155,6 @@ bool DccRecvThread::sendAck(int filePos,bool bTolerateErrors)
if(iRet < 0)
{
- if(bTolerateErrors)
- return true; // ignore at all
-
// Reported error. If it's EAGAIN or EINTR then no data has been sent.
#ifdef COMPILE_SSL_SUPPORT
if(m_pSSL)
@@ -196,24 +201,17 @@ bool DccRecvThread::sendAck(int filePos,bool bTolerateErrors)
// This will probably throttle the bandwidth usage a bit too.
msleep(10);
- int iMissingPart = 4 - iRet;
+ int iMissingPart = ackSize - iRet;
#ifdef COMPILE_SSL_SUPPORT
if(m_pSSL)
- {
- iRet = m_pSSL->write(((char*)(&size)) + iRet,iMissingPart);
- } else {
-#endif //COMPILE_SSL_SUPPORT
- iRet = kvi_socket_send(m_fd,(void *)(((char *)(&size)) + iRet),iMissingPart);
-#ifdef COMPILE_SSL_SUPPORT
- }
+ iRet = m_pSSL->write(ack + iRet,iMissingPart);
+ else
#endif //COMPILE_SSL_SUPPORT
+ iRet = kvi_socket_send(m_fd,(void *)(ack + iRet),iMissingPart);
if(iRet != iMissingPart)
{
- if(bTolerateErrors)
- return true; // ignore at all
-
// Crap.. couldn't send the missing part of the ack :/
postErrorEvent(KviError::AcknowledgeError);
return false;
@@ -290,6 +288,8 @@ void DccRecvThread::run()
m_pFile = new QFile(QString::fromUtf8(m_pOpt->szFileName.ptr()));
+ bool bSend64BitAck = m_pOpt->bSend64BitAck && (m_pOpt->uTotalFileSize >> 32);
+
if(m_pOpt->bResume)
{
if(!m_pFile->open(QIODevice::WriteOnly | QIODevice::Append))
@@ -307,7 +307,7 @@ void DccRecvThread::run()
if(m_pOpt->bSendZeroAck && (!m_pOpt->bNoAcks))
{
- if(!sendAck(m_pFile->pos(),false))
+ if(!sendAck(m_pFile->pos(),bSend64BitAck))
goto exit_dcc;
}
@@ -407,14 +407,7 @@ void DccRecvThread::run()
} else {
// Must send the ack... the peer must close the connection
- // We tolerate ack errors if we're in the last 90% of the file.
- // It might be that we're slow with receiving data but the server
- // has already closed the connection (buggy server though).
-
- bool bTolerateErrors = (m_pOpt->uTotalFileSize > 0) &&
- (((quint64)m_pFile->pos()) >= (m_pOpt->uTotalFileSize - (m_pOpt->uTotalFileSize / 10)));
-
- if(!sendAck(m_pFile->pos(),bTolerateErrors))
+ if(!sendAck(m_pFile->pos(),bSend64BitAck))
break;
}
@@ -2119,6 +2112,7 @@ void DccFileTransfer::connected()
o->iIdleStepLengthInMSec = KVI_OPTION_BOOL(KviOption_boolDccSendForceIdleStep) ? KVI_OPTION_UINT(KviOption_uintDccSendIdleStepInMSec) : 0;
o->bIsTdcc = m_pDescriptor->bIsTdcc;
o->bSendZeroAck = KVI_OPTION_BOOL(KviOption_boolSendZeroAckInDccRecv);
+ o->bSend64BitAck = KVI_OPTION_BOOL(KviOption_boolSend64BitAckInDccRecv);
o->bNoAcks = m_pDescriptor->bNoAcks;
o->uMaxBandwidth = m_uMaxBandwidth;
m_pSlaveRecvThread = new DccRecvThread(this,m_pMarshal->releaseSocket(),o);
diff --git a/src/modules/dcc/DccFileTransfer.h b/src/modules/dcc/DccFileTransfer.h
index fea2d6467..d8f9cb11d 100644
--- a/src/modules/dcc/DccFileTransfer.h
+++ b/src/modules/dcc/DccFileTransfer.h
@@ -53,7 +53,7 @@ class QMenu;
typedef struct _KviDccSendThreadOptions
{
- KviCString szFileName;
+ KviCString szFileName;
quint64 uStartPosition;
int iPacketSize;
int iIdleStepLengthInMSec;
@@ -101,10 +101,11 @@ protected:
typedef struct _KviDccRecvThreadOptions
{
bool bResume;
- KviCString szFileName;
+ KviCString szFileName;
quint64 uTotalFileSize;
int iIdleStepLengthInMSec;
bool bSendZeroAck;
+ bool bSend64BitAck;
bool bNoAcks;
bool bIsTdcc;
unsigned int uMaxBandwidth;
@@ -127,7 +128,7 @@ protected:
// internal
unsigned long m_uStartTime;
KviMSecTimeInterval * m_pTimeInterval; // used for computing the instant bandwidth
- quint64 m_uInstantReceivedBytes;
+ quint64 m_uInstantReceivedBytes;
quint64 m_uInstantSpeedInterval;
QFile * m_pFile;
public:
@@ -143,7 +144,7 @@ public:
protected:
void postMessageEvent(const char * msg);
void updateStats();
- bool sendAck(int filePos,bool bTolerateErrors = false);
+ bool sendAck(qint64 filePos, bool bUse64BitAck = false);
virtual void run();
};
@@ -174,13 +175,13 @@ public:
DccFileTransfer(DccDescriptor * dcc);
~DccFileTransfer();
private:
- DccSendThread * m_pSlaveSendThread;
- DccRecvThread * m_pSlaveRecvThread;
- DccDescriptor * m_pDescriptor;
- DccMarshal * m_pMarshal;
+ DccSendThread * m_pSlaveSendThread;
+ DccRecvThread * m_pSlaveRecvThread;
+ DccDescriptor * m_pDescriptor;
+ DccMarshal * m_pMarshal;
- KviCString m_szTarget;
- KviCString m_szDccType;
+ KviCString m_szTarget;
+ KviCString m_szDccType;
QString m_szTransferIdString;
QString m_szStatusString;
diff --git a/src/modules/options/OptionsWidget_dcc.cpp b/src/modules/options/OptionsWidget_dcc.cpp
index 28564cb24..9674351ee 100644
--- a/src/modules/options/OptionsWidget_dcc.cpp
+++ b/src/modules/options/OptionsWidget_dcc.cpp
@@ -235,6 +235,11 @@ OptionsWidget_dccSendAdvanced::OptionsWidget_dccSendAdvanced(QWidget * parent)
__tr2qs_ctx("<center>This option causes KVIrc to replace spaces with underscores in filenames " \
"for all the outgoing file transfers. This will fix filename handling with some buggy clients (e.g. some versions of mIRC).","options"));
+ b = addBoolSelector(g,__tr2qs_ctx("Send 64-bit ACKs for files larger than 4GiB","options"),KviOption_boolSend64BitAckInDccRecv);
+ mergeTip(b,
+ __tr2qs_ctx("<center>This option causes KVIrc to send ACKs as 64-bit integers instead of 32-bit integers<br>" \
+ "Use this to fix DCC RECEIVE transfers where the other client is using the mIRC ACK standard.</center>","options"));
+
g = addGroupBox(0,1,0,1,Qt::Horizontal,__tr2qs_ctx("Limits","options"));
KviTalHBox * hb = new KviTalHBox(g);