summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/m_netlib.h14
-rw-r--r--libs/win32/mir_app.libbin225554 -> 225562 bytes
-rw-r--r--libs/win64/mir_app.libbin221278 -> 221278 bytes
-rw-r--r--plugins/CrashDumper/src/crshdmp.cpp2
-rw-r--r--plugins/Ping/src/utils.cpp9
-rw-r--r--plugins/Watrack_MPD/src/main.cpp8
-rw-r--r--protocols/Facebook/src/server.cpp6
-rw-r--r--protocols/IRCG/src/irclib.cpp19
-rw-r--r--protocols/JabberG/jabber.vcxproj1
-rw-r--r--protocols/JabberG/jabber.vcxproj.filters3
-rw-r--r--protocols/JabberG/src/jabber_byte.cpp16
-rw-r--r--protocols/JabberG/src/jabber_file.cpp7
-rw-r--r--protocols/JabberG/src/jabber_proto.cpp8
-rw-r--r--protocols/JabberG/src/jabber_proto.h13
-rw-r--r--protocols/JabberG/src/jabber_thread.cpp48
-rw-r--r--protocols/JabberG/src/jabber_ws.cpp72
-rw-r--r--protocols/JabberG/src/jabber_zstream.cpp8
-rw-r--r--protocols/JabberG/src/stdafx.h4
-rw-r--r--protocols/Sametime/src/sametime_session.cpp14
-rw-r--r--protocols/YAMN/src/proto/netlib.cpp5
-rw-r--r--src/mir_app/src/mir_app.def1
-rw-r--r--src/mir_app/src/mir_app64.def1
-rw-r--r--src/mir_app/src/netlib.h9
-rw-r--r--src/mir_app/src/netlib_autoproxy.cpp10
-rw-r--r--src/mir_app/src/netlib_http.cpp36
-rw-r--r--src/mir_app/src/netlib_openconn.cpp269
-rw-r--r--src/mir_app/src/netlib_ssl.cpp2
27 files changed, 156 insertions, 429 deletions
diff --git a/include/m_netlib.h b/include/m_netlib.h
index df2b649361..867cdd974f 100644
--- a/include/m_netlib.h
+++ b/include/m_netlib.h
@@ -310,22 +310,10 @@ EXTERN_C MIR_APP_DLL(HNETLIBBIND) Netlib_BindPort(HNETLIBUSER nlu, NETLIBBIND *n
#define NLOCF_HTTP 0x0001 // this connection will be used for HTTP communications. If configured for an HTTP/HTTPS proxy the connection is opened as if there was no proxy.
#define NLOCF_STICKYHEADERS 0x0002 // this connection should send the sticky headers associated with NetLib user apart of any HTTP request
-#define NLOCF_V2 0x0004 // this connection understands the newer structure, newer cbSize isnt enough
#define NLOCF_UDP 0x0008 // this connection is UDP
#define NLOCF_SSL 0x0010 // this connection is SSL
-struct NETLIBOPENCONNECTION
-{
- const char *szHost; // can contain the string representation of an IP
- uint16_t wPort; // host byte order
- uint32_t flags;
- unsigned int timeout;
- /* optional, called in the context of the thread that issued the attempt, if it returns 0 the connection attempt is
- stopped, the remaining timeout value can also be adjusted */
- int (*waitcallback) (unsigned int *timeout);
-};
-
-EXTERN_C MIR_APP_DLL(HNETLIBCONN) Netlib_OpenConnection(HNETLIBUSER nlu, const NETLIBOPENCONNECTION *nloc);
+EXTERN_C MIR_APP_DLL(HNETLIBCONN) Netlib_OpenConnection(HNETLIBUSER nlu, const char *szHost, int port, int timeout = 0, int flags = 0);
/////////////////////////////////////////////////////////////////////////////////////////
// Sets the required information for an HTTP proxy connection
diff --git a/libs/win32/mir_app.lib b/libs/win32/mir_app.lib
index 41f431c6ac..0ab0ca4970 100644
--- a/libs/win32/mir_app.lib
+++ b/libs/win32/mir_app.lib
Binary files differ
diff --git a/libs/win64/mir_app.lib b/libs/win64/mir_app.lib
index 6357328d82..870add873d 100644
--- a/libs/win64/mir_app.lib
+++ b/libs/win64/mir_app.lib
Binary files differ
diff --git a/plugins/CrashDumper/src/crshdmp.cpp b/plugins/CrashDumper/src/crshdmp.cpp
index 6d59149c3f..d204008dc1 100644
--- a/plugins/CrashDumper/src/crshdmp.cpp
+++ b/plugins/CrashDumper/src/crshdmp.cpp
@@ -111,7 +111,7 @@ INT_PTR GetVersionInfo(WPARAM wParam, LPARAM lParam)
return result;
}
-INT_PTR OpenUrl(WPARAM wParam, LPARAM)
+INT_PTR OpenUrl(WPARAM, LPARAM)
{
ShellExecute(nullptr, L"explore", CrashLogFolder, nullptr, nullptr, SW_SHOW);
return 0;
diff --git a/plugins/Ping/src/utils.cpp b/plugins/Ping/src/utils.cpp
index cf263026b5..e225d1f864 100644
--- a/plugins/Ping/src/utils.cpp
+++ b/plugins/Ping/src/utils.cpp
@@ -52,14 +52,7 @@ INT_PTR PluginPing(WPARAM, LPARAM lParam)
clock_t start_tcp = clock();
- //GetLocalTime(&systime);
- NETLIBOPENCONNECTION conn = {};
- conn.szHost = mir_u2a(pa->pszName);
- conn.wPort = pa->port;
- conn.timeout = options.ping_timeout;
-
- HNETLIBCONN s = Netlib_OpenConnection(hNetlibUser, &conn);
- mir_free((void *)conn.szHost);
+ HNETLIBCONN s = Netlib_OpenConnection(hNetlibUser, _T2A(pa->pszName), pa->port, options.ping_timeout);
clock_t end_tcp = clock();
diff --git a/plugins/Watrack_MPD/src/main.cpp b/plugins/Watrack_MPD/src/main.cpp
index fb5d454ab5..821e2f4074 100644
--- a/plugins/Watrack_MPD/src/main.cpp
+++ b/plugins/Watrack_MPD/src/main.cpp
@@ -24,14 +24,8 @@ SONGINFO SongInfo = {};
void Start(void*)
{
- NETLIBOPENCONNECTION nloc = {};
- char *tmp = (char*)mir_u2a(gbHost);
- nloc.szHost = tmp;
- nloc.timeout = 5;
- nloc.flags = NLOCF_V2;
- nloc.wPort = gbPort;
Connected = FALSE;
- ghConnection = Netlib_OpenConnection(ghNetlibUser, &nloc);
+ ghConnection = Netlib_OpenConnection(ghNetlibUser, _T2A(gbHost), gbPort, 5);
if (ghConnection)
ghPacketReciever = Netlib_CreatePacketReceiver(ghConnection, 2048);
}
diff --git a/protocols/Facebook/src/server.cpp b/protocols/Facebook/src/server.cpp
index caffa475a7..5b0a15ee13 100644
--- a/protocols/Facebook/src/server.cpp
+++ b/protocols/Facebook/src/server.cpp
@@ -402,11 +402,7 @@ LBL_Begin:
}
// connect to MQTT server
- NETLIBOPENCONNECTION nloc = {};
- nloc.szHost = "mqtt.facebook.com";
- nloc.wPort = 443;
- nloc.flags = NLOCF_SSL | NLOCF_V2;
- m_mqttConn = Netlib_OpenConnection(m_hNetlibUser, &nloc);
+ m_mqttConn = Netlib_OpenConnection(m_hNetlibUser, "mqtt.facebook.com", 443, 0, NLOCF_SSL);
if (m_mqttConn == nullptr) {
debugLogA("connection failed, exiting");
ConnectionFailed();
diff --git a/protocols/IRCG/src/irclib.cpp b/protocols/IRCG/src/irclib.cpp
index 4e17358632..b36e1b37e7 100644
--- a/protocols/IRCG/src/irclib.cpp
+++ b/protocols/IRCG/src/irclib.cpp
@@ -194,10 +194,7 @@ bool CIrcProto::Connect(const CIrcSessionInfo& info)
{
codepage = m_codepage;
- NETLIBOPENCONNECTION ncon = {};
- ncon.szHost = info.sServer.c_str();
- ncon.wPort = info.iPort;
- con = Netlib_OpenConnection(m_hNetlibUser, &ncon);
+ con = Netlib_OpenConnection(m_hNetlibUser, info.sServer, info.iPort);
if (con == nullptr) {
wchar_t szTemp[300];
mir_snwprintf(szTemp, L"%c5%s %c%s%c (%S: %u).", irc::COLOR, TranslateT("Failed to connect to"), irc::BOLD, m_tszUserName, irc::BOLD, m_sessionInfo.sServer.c_str(), m_sessionInfo.iPort);
@@ -856,12 +853,8 @@ int CDccSession::SetupConnection()
// If a remote computer initiates a chat session this is used to connect to the remote computer (user already accepted at this point).
// also used for connecting to a remote computer for remote file transfers
- if (di->iType == DCC_CHAT && !di->bSender || di->iType == DCC_SEND && di->bSender && di->bReverse) {
- NETLIBOPENCONNECTION ncon = {};
- ncon.szHost = ConvertIntegerToIP(di->dwAdr);
- ncon.wPort = (uint16_t)di->iPort;
- con = Netlib_OpenConnection(m_proto->hNetlibDCC, &ncon);
- }
+ if (di->iType == DCC_CHAT && !di->bSender || di->iType == DCC_SEND && di->bSender && di->bReverse)
+ con = Netlib_OpenConnection(m_proto->hNetlibDCC, ConvertIntegerToIP(di->dwAdr), di->iPort);
// If a remote computer initiates a filetransfer this is used to connect to that computer (the user has chosen to accept but it is possible the file exists/needs to be resumed etc still)
if (di->iType == DCC_SEND && !di->bSender) {
@@ -951,11 +944,7 @@ int CDccSession::SetupConnection()
}
// connect to the remote computer from which you are receiving the file (now all actions to take (resume/overwrite etc) have been decided
- NETLIBOPENCONNECTION ncon = {};
- ncon.szHost = ConvertIntegerToIP(di->dwAdr);
- ncon.wPort = (uint16_t)di->iPort;
-
- con = Netlib_OpenConnection(m_proto->hNetlibDCC, &ncon);
+ con = Netlib_OpenConnection(m_proto->hNetlibDCC, ConvertIntegerToIP(di->dwAdr), di->iPort);
}
// if for some reason the plugin has failed to connect to the remote computer the object is destroyed.
diff --git a/protocols/JabberG/jabber.vcxproj b/protocols/JabberG/jabber.vcxproj
index 7dc563d45a..632ea83ce6 100644
--- a/protocols/JabberG/jabber.vcxproj
+++ b/protocols/JabberG/jabber.vcxproj
@@ -76,7 +76,6 @@
<ClCompile Include="src\jabber_userinfo.cpp" />
<ClCompile Include="src\jabber_util.cpp" />
<ClCompile Include="src\jabber_vcard.cpp" />
- <ClCompile Include="src\jabber_ws.cpp" />
<ClCompile Include="src\jabber_xml.cpp" />
<ClCompile Include="src\jabber_xstatus.cpp" />
<ClCompile Include="src\jabber_zstream.cpp" />
diff --git a/protocols/JabberG/jabber.vcxproj.filters b/protocols/JabberG/jabber.vcxproj.filters
index b7205778b0..8f8f5a9e4e 100644
--- a/protocols/JabberG/jabber.vcxproj.filters
+++ b/protocols/JabberG/jabber.vcxproj.filters
@@ -149,9 +149,6 @@
<ClCompile Include="src\jabber_vcard.cpp">
<Filter>Source Files</Filter>
</ClCompile>
- <ClCompile Include="src\jabber_ws.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
<ClCompile Include="src\jabber_xml.cpp">
<Filter>Source Files</Filter>
</ClCompile>
diff --git a/protocols/JabberG/src/jabber_byte.cpp b/protocols/JabberG/src/jabber_byte.cpp
index 48c3c02463..685174347d 100644
--- a/protocols/JabberG/src/jabber_byte.cpp
+++ b/protocols/JabberG/src/jabber_byte.cpp
@@ -438,15 +438,9 @@ void CJabberProto::ByteSendViaProxy(JABBER_BYTE_TRANSFER *jbt)
char *szPort = jbt->szProxyPort;
char *szHost = jbt->szProxyHost;
- uint16_t port = (uint16_t)atoi(szPort);
replaceStr(jbt->streamhostJID, jbt->szProxyJid);
- NETLIBOPENCONNECTION nloc = {};
- nloc.szHost = szHost;
- nloc.wPort = port;
-
- HNETLIBCONN hConn = Netlib_OpenConnection(m_hNetlibUser, &nloc);
- mir_free((void*)nloc.szHost);
+ HNETLIBCONN hConn = Netlib_OpenConnection(m_hNetlibUser, szHost, atoi(szPort));
if (hConn != nullptr) {
jbt->hConn = hConn;
@@ -610,13 +604,7 @@ void __cdecl CJabberProto::ByteReceiveThread(JABBER_BYTE_TRANSFER *jbt)
replaceStr(jbt->streamhostJID, str);
debugLogA("bytestream_recv connecting to %s:%d", szHost, port);
- NETLIBOPENCONNECTION nloc = { 0 };
- nloc.szHost = mir_strdup(szHost);
- nloc.wPort = port;
-
- HNETLIBCONN hConn = Netlib_OpenConnection(m_hNetlibUser, &nloc);
- mir_free((void*)nloc.szHost);
-
+ HNETLIBCONN hConn = Netlib_OpenConnection(m_hNetlibUser, szHost, port);
if (hConn == nullptr) {
debugLogA("bytestream_recv_connection connection failed (%d), try next streamhost", WSAGetLastError());
continue;
diff --git a/protocols/JabberG/src/jabber_file.cpp b/protocols/JabberG/src/jabber_file.cpp
index f7d0cd0aac..b01b32f32a 100644
--- a/protocols/JabberG/src/jabber_file.cpp
+++ b/protocols/JabberG/src/jabber_file.cpp
@@ -36,10 +36,7 @@ void __cdecl CJabberProto::FileReceiveThread(filetransfer *ft)
ft->type = FT_OOB;
- NETLIBOPENCONNECTION nloc = {};
- nloc.szHost = ft->httpHostName;
- nloc.wPort = ft->httpPort;
- info.s = Netlib_OpenConnection(m_hNetlibUser, &nloc);
+ info.s = Netlib_OpenConnection(m_hNetlibUser, ft->httpHostName, ft->httpPort);
if (info.s == nullptr) {
debugLogA("Connection failed (%d), thread ended", WSAGetLastError());
ProtoBroadcastAck(ft->std.hContact, ACKTYPE_FILE, ACKRESULT_FAILED, ft);
@@ -401,7 +398,7 @@ int CJabberProto::FileSendParse(HNETLIBCONN s, filetransfer *ft, char* buffer, i
char fileBuffer[2048];
int bytes = mir_snprintf(fileBuffer, "HTTP/1.1 200 OK\r\nContent-Length: %d\r\n\r\n", _filelength(fileId));
- WsSend(s, fileBuffer, bytes, MSG_DUMPASTEXT);
+ Netlib_Send(s, fileBuffer, bytes, MSG_DUMPASTEXT);
ft->std.flags |= PFTS_SENDING;
ft->std.currentFileProgress = 0;
diff --git a/protocols/JabberG/src/jabber_proto.cpp b/protocols/JabberG/src/jabber_proto.cpp
index c2dc2d50e5..fb6fee3ce1 100644
--- a/protocols/JabberG/src/jabber_proto.cpp
+++ b/protocols/JabberG/src/jabber_proto.cpp
@@ -204,7 +204,6 @@ CJabberProto::CJabberProto(const char *aProtoName, const wchar_t *aUserName) :
IconsInit();
InitPopups();
GlobalMenuInit();
- WsInit();
m_pepServices.insert(new CPepMood(this));
m_pepServices.insert(new CPepActivity(this));
@@ -214,6 +213,13 @@ CJabberProto::CJabberProto(const char *aProtoName, const wchar_t *aUserName) :
OmemoInitDevice();
}
+ // network initialization
+ NETLIBUSER nlu = {};
+ nlu.flags = NUF_OUTGOING | NUF_INCOMING | NUF_HTTPCONNS | NUF_UNICODE;
+ nlu.szDescriptiveName.w = m_tszUserName;
+ nlu.szSettingsModule = m_szModuleName;
+ m_hNetlibUser = Netlib_RegisterUser(&nlu);
+
// group chats
GCREGISTER gcr = {};
gcr.dwFlags = GC_TYPNOTIF | GC_CHANMGR;
diff --git a/protocols/JabberG/src/jabber_proto.h b/protocols/JabberG/src/jabber_proto.h
index 823f17feff..9d87dbc775 100644
--- a/protocols/JabberG/src/jabber_proto.h
+++ b/protocols/JabberG/src/jabber_proto.h
@@ -76,6 +76,8 @@ struct CChatMark
struct CJabberProto : public PROTO<CJabberProto>, public IJabberInterface
{
+ friend struct ThreadData;
+
class CJabberProtoImpl
{
friend struct CJabberProto;
@@ -240,6 +242,7 @@ struct CJabberProto : public PROTO<CJabberProto>, public IJabberInterface
CMOption<uint32_t> m_iConnectionKeepAliveTimeout;
PVOID m_sslCtx;
+ mir_cs m_csSocket; // protects i/o operations
HANDLE m_hThreadHandle;
@@ -883,14 +886,6 @@ struct CJabberProto : public PROTO<CJabberProto>, public IJabberInterface
void SetServerVcard(BOOL bPhotoChanged, wchar_t* szPhotoFileName);
void SaveVcardToDB(HWND hwndPage, int iPage);
- //---- jabber_ws.c -------------------------------------------------
-
- HNETLIBCONN WsConnect(char* host, uint16_t port);
-
- bool WsInit(void);
- int WsSend(HNETLIBCONN s, char* data, int datalen, int flags);
- int WsRecv(HNETLIBCONN s, char* data, long datalen, int flags);
-
//---- jabber_xml.c ------------------------------------------------------------------
void OnConsoleProcessXml(const TiXmlElement *node, uint32_t flags);
@@ -929,8 +924,6 @@ struct CJabberProto : public PROTO<CJabberProto>, public IJabberInterface
private:
char *m_szXmlStreamToBeInitialized;
- uint32_t m_lastTicks;
-
HANDLE m_hPopupClass;
LONG m_nSerial;
diff --git a/protocols/JabberG/src/jabber_thread.cpp b/protocols/JabberG/src/jabber_thread.cpp
index dcd5e5d6b7..0dbf3a1ba9 100644
--- a/protocols/JabberG/src/jabber_thread.cpp
+++ b/protocols/JabberG/src/jabber_thread.cpp
@@ -141,16 +141,15 @@ void CJabberProto::JLoginFailed(int errorCode)
void CJabberProto::CheckKeepAlive()
{
- if (GetTickCount() - m_lastTicks < m_iConnectionKeepAliveInterval)
- return;
-
- if (m_bKeepAlive && m_ThreadInfo) {
- if (m_ThreadInfo->jabberServerCaps & JABBER_CAPS_PING) {
- CJabberIqInfo *pInfo = AddIQ(&CJabberProto::OnPingReply, JABBER_IQ_TYPE_GET, nullptr, this);
- pInfo->SetTimeout(m_iConnectionKeepAliveTimeout);
- m_ThreadInfo->send(XmlNodeIq(pInfo) << XATTR("from", m_ThreadInfo->fullJID) << XCHILDNS("ping", JABBER_FEAT_PING));
+ if (m_ThreadInfo) {
+ if (m_bKeepAlive && ::GetTickCount() - m_ThreadInfo->lastWriteTime < m_iConnectionKeepAliveInterval) {
+ if (m_ThreadInfo->jabberServerCaps & JABBER_CAPS_PING) {
+ CJabberIqInfo *pInfo = AddIQ(&CJabberProto::OnPingReply, JABBER_IQ_TYPE_GET, nullptr, this);
+ pInfo->SetTimeout(m_iConnectionKeepAliveTimeout);
+ m_ThreadInfo->send(XmlNodeIq(pInfo) << XATTR("from", m_ThreadInfo->fullJID) << XCHILDNS("ping", JABBER_FEAT_PING));
+ }
+ else m_ThreadInfo->send(" \t ");
}
- else m_ThreadInfo->send(" \t ");
}
if (m_bEnableStreamMgmt)
@@ -192,7 +191,7 @@ void ThreadData::xmpp_client_query(void)
char* dnsHost = it->pNameTarget;
proto->debugLogA("%s%s resolved to %s:%d", "_xmpp-client._tcp.", conn.server, dnsHost, dnsPort);
- s = proto->WsConnect(dnsHost, dnsPort);
+ s = Netlib_OpenConnection(proto->m_hNetlibUser, dnsHost, dnsPort);
if (s) {
strncpy_s(conn.manualHost, dnsHost, _TRUNCATE);
conn.port = dnsPort;
@@ -375,10 +374,10 @@ LBL_FatalError:
info.xmpp_client_query();
if (info.s == nullptr) {
strncpy_s(info.conn.manualHost, info.conn.server, _TRUNCATE);
- info.s = WsConnect(info.conn.manualHost, info.conn.port);
+ info.s = Netlib_OpenConnection(m_hNetlibUser, info.conn.manualHost, info.conn.port);
}
}
- else info.s = WsConnect(info.conn.manualHost, info.conn.port);
+ else info.s = Netlib_OpenConnection(m_hNetlibUser, info.conn.manualHost, info.conn.port);
debugLogA("Thread type=%d server='%s' port='%d'", info.bIsReg, info.conn.manualHost, info.conn.port);
if (info.s == nullptr) {
@@ -424,7 +423,7 @@ LBL_FatalError:
debugLogA("Entering main recv loop");
int datalen = 0;
- // cache values
+ // main socket reading cycle
for (;;) {
int recvResult = info.recv(info.buffer + datalen, jabberNetworkBufferSize - datalen);
debugLogA("recvResult = %d", recvResult);
@@ -1958,7 +1957,7 @@ ThreadData::ThreadData(CJabberProto *_pro, JABBER_CONN_DATA *param)
resolveID = -1;
proto = _pro;
- iomutex = CreateMutex(nullptr, FALSE, nullptr);
+ lastWriteTime = ::GetTickCount();
if (param != nullptr) {
bIsReg = true;
@@ -1974,8 +1973,6 @@ ThreadData::~ThreadData()
mir_free(gssapiHostName);
mir_free(zRecvData);
mir_free(buffer);
-
- CloseHandle(iomutex);
}
void ThreadData::close(void)
@@ -1997,10 +1994,20 @@ int ThreadData::recv(char* buf, size_t len)
if (this == nullptr)
return 0;
+ // this select() is still required because shitty openssl is not thread safe
+ if (zRecvReady) {
+ NETLIBSELECT nls = {};
+ nls.dwTimeout = INFINITE;
+ nls.hReadConns[0] = s;
+ int nSelRes = Netlib_Select(&nls);
+ if (nSelRes == SOCKET_ERROR) // error
+ return SOCKET_ERROR;
+ }
+
if (useZlib)
return zlibRecv(buf, (long)len);
- return proto->WsRecv(s, buf, (long)len, MSG_DUMPASTEXT);
+ return Netlib_Recv(s, buf, (long)len, MSG_DUMPASTEXT);
}
int ThreadData::send(char* buf, int bufsize)
@@ -2008,22 +2015,21 @@ int ThreadData::send(char* buf, int bufsize)
if (this == nullptr)
return 0;
+ lastWriteTime = ::GetTickCount();
if (bufsize == -1)
bufsize = (int)mir_strlen(buf);
- WaitForSingleObject(iomutex, 6000);
+ mir_cslock lck(proto->m_csSocket);
int result;
if (useZlib)
result = zlibSend(buf, bufsize);
else
- result = proto->WsSend(s, buf, bufsize, MSG_DUMPASTEXT);
+ result = Netlib_Send(s, buf, bufsize, MSG_DUMPASTEXT);
if (result == SOCKET_ERROR)
close();
- ReleaseMutex(iomutex);
-
return result;
}
diff --git a/protocols/JabberG/src/jabber_ws.cpp b/protocols/JabberG/src/jabber_ws.cpp
deleted file mode 100644
index 3f70f1d6c1..0000000000
--- a/protocols/JabberG/src/jabber_ws.cpp
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
-
-Jabber Protocol Plugin for Miranda NG
-
-Copyright (c) 2002-04 Santithorn Bunchua
-Copyright (c) 2005-12 George Hazan
-Copyright (C) 2012-22 Miranda NG team
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-*/
-
-#include "stdafx.h"
-
-bool CJabberProto::WsInit(void)
-{
- m_lastTicks = ::GetTickCount();
-
-
- NETLIBUSER nlu = {};
- nlu.flags = NUF_OUTGOING | NUF_INCOMING | NUF_HTTPCONNS | NUF_UNICODE;
- nlu.szDescriptiveName.w = m_tszUserName;
- nlu.szSettingsModule = m_szModuleName;
- m_hNetlibUser = Netlib_RegisterUser(&nlu);
- return m_hNetlibUser != nullptr;
-}
-
-HNETLIBCONN CJabberProto::WsConnect(char* host, uint16_t port)
-{
- NETLIBOPENCONNECTION nloc = {};
- nloc.szHost = host;
- nloc.wPort = port;
- nloc.timeout = 6;
- return Netlib_OpenConnection(m_hNetlibUser, &nloc);
-}
-
-int CJabberProto::WsSend(HNETLIBCONN hConn, char* data, int datalen, int flags)
-{
- m_lastTicks = ::GetTickCount();
- int ret = Netlib_Send(hConn, data, datalen, flags);
- if (ret == SOCKET_ERROR || ret != datalen) {
- debugLogA("Netlib_Send() failed, error=%d", WSAGetLastError());
- return SOCKET_ERROR;
- }
- return ret;
-}
-
-int CJabberProto::WsRecv(HNETLIBCONN hConn, char* data, long datalen, int flags)
-{
- int ret = Netlib_Recv(hConn, data, datalen, flags);
- if (ret == SOCKET_ERROR) {
- debugLogA("Netlib_Recv() failed, error=%d", WSAGetLastError());
- return 0;
- }
- if (ret == 0) {
- debugLogA("Connection closed gracefully");
- return 0;
- }
- return ret;
-}
diff --git a/protocols/JabberG/src/jabber_zstream.cpp b/protocols/JabberG/src/jabber_zstream.cpp
index ec3a7ca3b7..0931e4fc34 100644
--- a/protocols/JabberG/src/jabber_zstream.cpp
+++ b/protocols/JabberG/src/jabber_zstream.cpp
@@ -72,7 +72,7 @@ int ThreadData::zlibSend(char* data, int datalen)
}
int send_datalen = ZLIB_CHUNK_SIZE - zStreamOut.avail_out;
- int len = proto->WsSend(s, send_data, send_datalen, MSG_NODUMP);
+ int len = Netlib_Send(s, send_data, send_datalen, MSG_NODUMP);
if (len == SOCKET_ERROR || len != send_datalen) {
proto->debugLogA("Netlib_Send() failed, error=%d", WSAGetLastError());
return SOCKET_ERROR;
@@ -92,13 +92,15 @@ int ThreadData::zlibRecv(char* data, long datalen)
{
if (zRecvReady) {
retry:
- zRecvDatalen = proto->WsRecv(s, zRecvData, ZLIB_CHUNK_SIZE, MSG_NODUMP);
+ zRecvDatalen = Netlib_Recv(s, zRecvData, ZLIB_CHUNK_SIZE, MSG_NODUMP);
if (zRecvDatalen == SOCKET_ERROR) {
proto->debugLogA("Netlib_Recv() failed, error=%d", WSAGetLastError());
return SOCKET_ERROR;
}
- if (zRecvDatalen == 0)
+ if (zRecvDatalen == 0) {
+ proto->debugLogA("Connection closed gracefully");
return 0;
+ }
zStreamIn.avail_in = zRecvDatalen;
zStreamIn.next_in = (Bytef*)zRecvData;
diff --git a/protocols/JabberG/src/stdafx.h b/protocols/JabberG/src/stdafx.h
index 8d56126b59..cf41737088 100644
--- a/protocols/JabberG/src/stdafx.h
+++ b/protocols/JabberG/src/stdafx.h
@@ -339,10 +339,10 @@ struct ThreadData
ptrA szStreamId;
char* buffer;
+ uint32_t lastWriteTime; // in ticks
// network support
HNETLIBCONN s;
- HANDLE iomutex; // protects i/o operations
CJabberProto *proto;
// XEP-0138 (Compression support)
@@ -367,7 +367,7 @@ struct ThreadData
bool bIsReg;
bool reg_done, bIsSessionAvailable;
bool bBookmarksLoaded;
- uint32_t dwLoginRqs;
+ uint32_t dwLoginRqs;
// connection & login data
JABBER_CONN_DATA conn;
diff --git a/protocols/Sametime/src/sametime_session.cpp b/protocols/Sametime/src/sametime_session.cpp
index 84d8ed15d2..18475f0ea8 100644
--- a/protocols/Sametime/src/sametime_session.cpp
+++ b/protocols/Sametime/src/sametime_session.cpp
@@ -358,11 +358,6 @@ void __cdecl CSametimeProto::KeepAliveThread(void*)
return;
}
-int waitcallback(unsigned int*)
-{
- return continue_connect ? 1 : 0;
-}
-
void __cdecl CSametimeProto::SessionThread(LPVOID)
{
debugLogW(L"SessionThread() start");
@@ -372,14 +367,7 @@ void __cdecl CSametimeProto::SessionThread(LPVOID)
BroadcastNewStatus(ID_STATUS_CONNECTING);
// setup
- NETLIBOPENCONNECTION conn_data = { 0 };
- conn_data.flags = NLOCF_V2;
- conn_data.szHost = options.server_name;
- conn_data.wPort = options.port;
- conn_data.timeout = 20;
- conn_data.waitcallback = waitcallback;
- server_connection = Netlib_OpenConnection(m_hNetlibUser, &conn_data);
-
+ server_connection = Netlib_OpenConnection(m_hNetlibUser, options.server_name, options.port, 20);
if (!server_connection) {
BroadcastNewStatus(ID_STATUS_OFFLINE);
diff --git a/protocols/YAMN/src/proto/netlib.cpp b/protocols/YAMN/src/proto/netlib.cpp
index 34366fa734..29222dd980 100644
--- a/protocols/YAMN/src/proto/netlib.cpp
+++ b/protocols/YAMN/src/proto/netlib.cpp
@@ -88,10 +88,7 @@ void CNLClient::Connect(const char* servername, const int port) throw(DWORD)
DebugLog(CommFile, "<connect>\n");
#endif
try {
- NETLIBOPENCONNECTION nloc = {};
- nloc.szHost = servername;
- nloc.wPort = port;
- if (nullptr == (hConnection = Netlib_OpenConnection(hNetlibUser, &nloc))) {
+ if (nullptr == (hConnection = Netlib_OpenConnection(hNetlibUser, servername, port))) {
SystemError = WSAGetLastError();
throw NetworkError = (uint32_t)ENL_CONNECT;
}
diff --git a/src/mir_app/src/mir_app.def b/src/mir_app/src/mir_app.def
index 57ce92f4f5..bd1cb17638 100644
--- a/src/mir_app/src/mir_app.def
+++ b/src/mir_app/src/mir_app.def
@@ -795,3 +795,4 @@ _Netlib_SslWrite@12 @877 NONAME
Srmm_GetButtonGap @883
?addPopupOption@CMPluginBase@@QAEHPBDAAV?$CMOption@_N@@@Z @884 NONAME
?addPopupOption@CMPluginBase@@QAEHPB_WAAV?$CMOption@_N@@@Z @885 NONAME
+Srmm_CreateHotkey @886 NONAME
diff --git a/src/mir_app/src/mir_app64.def b/src/mir_app/src/mir_app64.def
index 0e11cd8e6e..542d588276 100644
--- a/src/mir_app/src/mir_app64.def
+++ b/src/mir_app/src/mir_app64.def
@@ -795,3 +795,4 @@ Netlib_SslWrite @877 NONAME
Srmm_GetButtonGap @883
?addPopupOption@CMPluginBase@@QEAAHPEBDAEAV?$CMOption@_N@@@Z @884 NONAME
?addPopupOption@CMPluginBase@@QEAAHPEB_WAEAV?$CMOption@_N@@@Z @885 NONAME
+Srmm_CreateHotkey @886 NONAME
diff --git a/src/mir_app/src/netlib.h b/src/mir_app/src/netlib.h
index 06d59a3688..0087c4b05f 100644
--- a/src/mir_app/src/netlib.h
+++ b/src/mir_app/src/netlib.h
@@ -65,6 +65,12 @@ union SOCKADDR_INET_M
USHORT si_family;
};
+struct NetlibUrl
+{
+ CMStringA szHost;
+ int flags = 0, port = 0;
+};
+
struct NetlibConnection : public MZeroedObject
{
NetlibConnection();
@@ -77,7 +83,8 @@ struct NetlibConnection : public MZeroedObject
bool termRequested;
NetlibUser *nlu;
- NETLIBOPENCONNECTION nloc;
+ NetlibUrl url;
+ int timeout;
char *szNewUrl;
diff --git a/src/mir_app/src/netlib_autoproxy.cpp b/src/mir_app/src/netlib_autoproxy.cpp
index 0da7aa80ac..cc2ef2b9e1 100644
--- a/src/mir_app/src/netlib_autoproxy.cpp
+++ b/src/mir_app/src/netlib_autoproxy.cpp
@@ -79,14 +79,14 @@ bool NetlibGetIeProxyConn(NetlibConnection *nlc, bool forceHttps)
bool usingSsl = false;
char szUrl[1024];
- if ((nlc->nloc.flags & NLOCF_HTTP) && (nlc->nloc.flags & NLOCF_SSL) || nlc->nloc.wPort == 443 || forceHttps) {
- mir_snprintf(szUrl, "https://%s", nlc->nloc.szHost);
+ if ((nlc->url.flags & NLOCF_HTTP) && (nlc->url.flags & NLOCF_SSL) || nlc->url.port == 443 || forceHttps) {
+ mir_snprintf(szUrl, "https://%s", nlc->url.szHost.c_str());
usingSsl = true;
}
- else if ((nlc->nloc.flags & NLOCF_HTTP))
- mir_snprintf(szUrl, "http://%s", nlc->nloc.szHost);
+ else if ((nlc->url.flags & NLOCF_HTTP))
+ mir_snprintf(szUrl, "http://%s", nlc->url.szHost.c_str());
else {
- strncpy_s(szUrl, nlc->nloc.szHost, _TRUNCATE);
+ strncpy_s(szUrl, nlc->url.szHost, _TRUNCATE);
noHttp = true;
}
diff --git a/src/mir_app/src/netlib_http.cpp b/src/mir_app/src/netlib_http.cpp
index c2e8275485..3ab187389b 100644
--- a/src/mir_app/src/netlib_http.cpp
+++ b/src/mir_app/src/netlib_http.cpp
@@ -143,7 +143,9 @@ static char* NetlibHttpFindAuthHeader(NETLIBHTTPREQUEST *nlhrReply, const char *
return nullptr;
}
-void NetlibConnFromUrl(const char *szUrl, bool secur, NETLIBOPENCONNECTION &nloc)
+/////////////////////////////////////////////////////////////////////////////////////////
+
+void NetlibConnFromUrl(const char *szUrl, bool secur, NetlibUrl &url)
{
secur = secur || _strnicmp(szUrl, "https", 5) == 0;
const char* phost = strstr(szUrl, "://");
@@ -153,48 +155,44 @@ void NetlibConnFromUrl(const char *szUrl, bool secur, NETLIBOPENCONNECTION &nloc
char* ppath = strchr(szHost, '/');
if (ppath) *ppath = '\0';
- memset(&nloc, 0, sizeof(nloc));
- nloc.szHost = szHost;
+ url.szHost = szHost;
char* pcolon = strrchr(szHost, ':');
if (pcolon) {
*pcolon = '\0';
- nloc.wPort = (uint16_t)strtol(pcolon+1, nullptr, 10);
+ url.port = strtol(pcolon+1, nullptr, 10);
}
- else nloc.wPort = secur ? 443 : 80;
- nloc.flags = (secur ? NLOCF_SSL : 0);
+ else url.port = secur ? 443 : 80;
+ url.flags = (secur ? NLOCF_SSL : 0);
}
static NetlibConnection* NetlibHttpProcessUrl(NETLIBHTTPREQUEST *nlhr, NetlibUser *nlu, NetlibConnection *nlc, const char *szUrl = nullptr)
{
- NETLIBOPENCONNECTION nloc;
+ NetlibUrl url;
if (szUrl == nullptr)
- NetlibConnFromUrl(nlhr->szUrl, (nlhr->flags & NLHRF_SSL) != 0, nloc);
+ NetlibConnFromUrl(nlhr->szUrl, (nlhr->flags & NLHRF_SSL) != 0, url);
else
- NetlibConnFromUrl(szUrl, false, nloc);
+ NetlibConnFromUrl(szUrl, false, url);
- nloc.flags |= NLOCF_HTTP;
- if (nloc.flags & NLOCF_SSL)
+ url.flags |= NLOCF_HTTP;
+ if (url.flags & NLOCF_SSL)
nlhr->flags |= NLHRF_SSL;
else
nlhr->flags &= ~NLHRF_SSL;
if (nlc != nullptr) {
- bool httpProxy = !(nloc.flags & NLOCF_SSL) && nlc->proxyType == PROXYTYPE_HTTP;
- bool sameHost = mir_strcmp(nlc->nloc.szHost, nloc.szHost) == 0 && nlc->nloc.wPort == nloc.wPort;
+ bool httpProxy = !(url.flags & NLOCF_SSL) && nlc->proxyType == PROXYTYPE_HTTP;
+ bool sameHost = mir_strcmp(nlc->url.szHost, url.szHost) == 0 && nlc->url.port == url.port;
if (!httpProxy && !sameHost) {
NetlibDoCloseSocket(nlc);
- mir_free((char*)nlc->nloc.szHost);
- nlc->nloc = nloc;
+ nlc->url = url;
return NetlibDoConnect(nlc) ? nlc : nullptr;
}
}
- else nlc = (NetlibConnection*)Netlib_OpenConnection(nlu, &nloc);
-
- mir_free((char*)nloc.szHost);
+ else nlc = (NetlibConnection*)Netlib_OpenConnection(nlu, url.szHost, url.port, 0, url.flags);
return nlc;
}
@@ -1145,7 +1143,7 @@ next:
}
if (close &&
- (nlc->proxyType != PROXYTYPE_HTTP || nlc->nloc.flags & NLOCF_SSL) &&
+ (nlc->proxyType != PROXYTYPE_HTTP || nlc->url.flags & NLOCF_SSL) &&
(!isConnect || nlhrReply->resultCode != 200))
NetlibDoCloseSocket(nlc);
diff --git a/src/mir_app/src/netlib_openconn.cpp b/src/mir_app/src/netlib_openconn.cpp
index b462e48721..b131b02f4e 100644
--- a/src/mir_app/src/netlib_openconn.cpp
+++ b/src/mir_app/src/netlib_openconn.cpp
@@ -109,28 +109,31 @@ bool RecvUntilTimeout(NetlibConnection *nlc, char *buf, int len, int flags, uint
return false;
}
-static int NetlibInitSocks4Connection(NetlibConnection *nlc, NetlibUser *nlu, NETLIBOPENCONNECTION *nloc)
+static int NetlibInitSocks4Connection(NetlibConnection *nlc)
{
// http://www.socks.nec.com/protocol/socks4.protocol and http://www.socks.nec.com/protocol/socks4a.protocol
- if (!nloc || !nloc->szHost || !nloc->szHost[0]) return 0;
+ NetlibUrl &url = nlc->url;
+ if (url.szHost.IsEmpty())
+ return 0;
- size_t nHostLen = mir_strlen(nloc->szHost) + 1;
+ NetlibUser *nlu = nlc->nlu;
+ size_t nHostLen = mir_strlen(url.szHost) + 1;
size_t nUserLen = nlu->settings.szProxyAuthUser ? mir_strlen(nlu->settings.szProxyAuthUser) + 1 : 1;
size_t len = 8 + nUserLen;
char* pInit = (char*)alloca(len + nHostLen);
pInit[0] = 4; // SOCKS4
pInit[1] = 1; //connect
- *(PWORD)&pInit[2] = htons(nloc->wPort);
+ *(PWORD)&pInit[2] = htons(url.port);
if (nUserLen <= 1) pInit[8] = 0;
else memcpy(&pInit[8], nlu->settings.szProxyAuthUser, nUserLen);
//if cannot resolve host, try resolving through proxy (requires SOCKS4a)
- uint32_t ip = DnsLookup(nlu, nloc->szHost);
+ uint32_t ip = DnsLookup(nlu, url.szHost);
*(PDWORD)&pInit[4] = ip ? ip : 0x01000000;
if (!ip) {
- memcpy(&pInit[len], nloc->szHost, nHostLen);
+ memcpy(&pInit[len], url.szHost, nHostLen);
len += nHostLen;
}
@@ -156,10 +159,11 @@ static int NetlibInitSocks4Connection(NetlibConnection *nlc, NetlibUser *nlu, NE
return 0;
}
-static int NetlibInitSocks5Connection(NetlibConnection *nlc, NetlibUser *nlu, NETLIBOPENCONNECTION *nloc)
+static int NetlibInitSocks5Connection(NetlibConnection *nlc)
{
//rfc1928
uint8_t buf[258];
+ NetlibUser *nlu = nlc->nlu;
buf[0] = 5; //yep, socks5
buf[1] = 1; //one auth method
@@ -210,30 +214,31 @@ static int NetlibInitSocks5Connection(NetlibConnection *nlc, NetlibUser *nlu, NE
size_t nHostLen;
uint32_t hostIP;
+ NetlibUrl &url = nlc->url;
if (nlc->dnsThroughProxy) {
- hostIP = inet_addr(nloc->szHost);
- nHostLen = (hostIP == INADDR_NONE) ? mir_strlen(nloc->szHost) + 1 : 4;
+ hostIP = inet_addr(url.szHost);
+ nHostLen = (hostIP == INADDR_NONE) ? mir_strlen(url.szHost) + 1 : 4;
}
else {
- hostIP = DnsLookup(nlu, nloc->szHost);
+ hostIP = DnsLookup(nlu, url.szHost);
if (hostIP == 0)
return 0;
nHostLen = 4;
}
uint8_t *pInit = (uint8_t*)mir_alloc(6 + nHostLen);
pInit[0] = 5; //SOCKS5
- pInit[1] = nloc->flags & NLOCF_UDP ? 3 : 1; //connect or UDP
+ pInit[1] = url.flags & NLOCF_UDP ? 3 : 1; //connect or UDP
pInit[2] = 0; //reserved
if (hostIP == INADDR_NONE) { //DNS lookup through proxy
pInit[3] = 3;
pInit[4] = uint8_t(nHostLen - 1);
- memcpy(pInit + 5, nloc->szHost, nHostLen - 1);
+ memcpy(pInit + 5, url.szHost, nHostLen - 1);
}
else {
pInit[3] = 1;
*(PDWORD)(pInit + 4) = hostIP;
}
- *(PWORD)(pInit + 4 + nHostLen) = htons(nloc->wPort);
+ *(PWORD)(pInit + 4 + nHostLen) = htons(url.port);
if (Netlib_Send(nlc, (char*)pInit, int(6 + nHostLen), MSG_DUMPPROXY) == SOCKET_ERROR) {
Netlib_Logf(nlu, "%s %d: %s() failed (%u)", __FILE__, __LINE__, "Netlib_Send", GetLastError());
mir_free(pInit);
@@ -291,16 +296,17 @@ static int NetlibInitSocks5Connection(NetlibConnection *nlc, NetlibUser *nlu, NE
return 1;
}
-static bool NetlibInitHttpsConnection(NetlibConnection *nlc, NetlibUser *nlu, NETLIBOPENCONNECTION *nloc)
+static bool NetlibInitHttpsConnection(NetlibConnection *nlc)
{
// rfc2817
+ NetlibUrl &url = nlc->url;
CMStringA szUrl;
if (nlc->dnsThroughProxy)
- szUrl.Format("%s:%u", nloc->szHost, nloc->wPort);
+ szUrl.Format("%s:%u", url.szHost.c_str(), url.port);
else {
- uint32_t ip = DnsLookup(nlu, nloc->szHost);
+ uint32_t ip = DnsLookup(nlc->nlu, url.szHost);
if (ip == 0) return false;
- szUrl.Format("%s:%u", inet_ntoa(*(PIN_ADDR)&ip), nloc->wPort);
+ szUrl.Format("%s:%u", inet_ntoa(*(PIN_ADDR)&ip), url.port);
}
NETLIBHTTPREQUEST nlhrSend = { 0 };
@@ -320,11 +326,12 @@ static bool NetlibInitHttpsConnection(NetlibConnection *nlc, NetlibUser *nlu, NE
if (nlhrReply->resultCode == 403 && nlc->dnsThroughProxy) {
Netlib_FreeHttpRequest(nlhrReply);
nlc->dnsThroughProxy = 0;
- return NetlibInitHttpsConnection(nlc, nlu, nloc);
+ return NetlibInitHttpsConnection(nlc);
}
NetlibHttpSetLastErrorUsingHttpResult(nlhrReply->resultCode);
- Netlib_Logf(nlu, "%s %d: %s request failed (%u %s)", __FILE__, __LINE__, nlu->settings.proxyType == PROXYTYPE_HTTP ? "HTTP" : "HTTPS", nlhrReply->resultCode, nlhrReply->szResultDescr);
+ Netlib_Logf(nlc->nlu, "%s %d: %s request failed (%u %s)", __FILE__, __LINE__,
+ nlc->nlu->settings.proxyType == PROXYTYPE_HTTP ? "HTTP" : "HTTPS", nlhrReply->resultCode, nlhrReply->szResultDescr);
Netlib_FreeHttpRequest(nlhrReply);
return 0;
}
@@ -342,160 +349,16 @@ static void FreePartiallyInitedConnection(NetlibConnection *nlc)
SetLastError(dwOriginalLastError);
}
-static bool my_connectIPv4(NetlibConnection *nlc, NETLIBOPENCONNECTION *nloc)
+static bool my_connectIP(NetlibConnection *nlc)
{
- int rc = 0, retrycnt = 0;
- u_long notblocking = 1;
- uint32_t lasterr = 0;
- static const TIMEVAL tv = { 1, 0 };
- NetlibUser *nlu = nlc->nlu;
-
- // if dwTimeout is zero then its an old style connection or new with a 0 timeout, select() will error quicker anyway
- unsigned int dwTimeout = (nloc && (nloc->flags & NLOCF_V2) && (nloc->timeout > 0)) ? nloc->timeout : 30;
-
- // this is for XP SP2 where there is a default connection attempt limit of 10/second
- if (connectionTimeout) {
- WaitForSingleObject(hConnectionOpenMutex, 10000);
- int waitdiff = GetTickCount() - g_LastConnectionTick;
- if (waitdiff < connectionTimeout) SleepEx(connectionTimeout, TRUE);
- g_LastConnectionTick = GetTickCount();
- ReleaseMutex(hConnectionOpenMutex);
-
- // might of died in between the wait
- if (Miranda_IsTerminated()) return false;
- }
-
- PHOSTENT he;
- sockaddr_in sin = { 0 };
- sin.sin_family = AF_INET;
-
- if (nlc->proxyType) {
- if (!nlc->szProxyServer) return false;
-
- if (nloc)
- Netlib_Logf(nlu, "(%p) Connecting to proxy %s:%d for %s:%d ....", nlc, nlc->szProxyServer, nlc->wProxyPort, nloc->szHost, nloc->wPort);
- else
- Netlib_Logf(nlu, "(%p) Connecting to proxy %s:%d ....", nlc, nlc->szProxyServer, nlc->wProxyPort);
-
- sin.sin_port = htons(nlc->wProxyPort);
- he = gethostbyname(nlc->szProxyServer);
- }
- else {
- if (!nloc || !nloc->szHost || nloc->szHost[0] == '[' || strchr(nloc->szHost, ':')) return false;
- Netlib_Logf(nlu, "(%p) Connecting to server %s:%d....", nlc, nloc->szHost, nloc->wPort);
-
- sin.sin_port = htons(nloc->wPort);
- he = gethostbyname(nloc->szHost);
- }
-
- for (char** har = he->h_addr_list; *har && !Miranda_IsTerminated(); ++har) {
- sin.sin_addr.s_addr = *(u_long*)*har;
-
- char *szIp = Netlib_AddressToString(&sin);
- Netlib_Logf(nlu, "(%p) Connecting to ip %s ....", nlc, szIp);
- mir_free(szIp);
-
-retry:
- nlc->s = socket(AF_INET, nloc->flags & NLOCF_UDP ? SOCK_DGRAM : SOCK_STREAM, 0);
- if (nlc->s == INVALID_SOCKET)
- return false;
-
- // return the socket to non blocking
- if (ioctlsocket(nlc->s, FIONBIO, &notblocking) != 0)
- return false;
-
- if (nlu->settings.specifyOutgoingPorts && nlu->settings.szOutgoingPorts && nlu->settings.szOutgoingPorts[0]) {
- if (!BindSocketToPort(nlu->settings.szOutgoingPorts, nlc->s, INVALID_SOCKET, &nlu->inportnum))
- Netlib_Logf(nlu, "Netlib connect: Not enough ports for outgoing connections specified");
- }
-
- // try a connect
- if (connect(nlc->s, (LPSOCKADDR)&sin, sizeof(sin)) == 0) {
- rc = 0;
- break;
- }
-
- // didn't work, was it cos of nonblocking?
- if (WSAGetLastError() != WSAEWOULDBLOCK) {
- rc = SOCKET_ERROR;
- closesocket(nlc->s);
- nlc->s = INVALID_SOCKET;
- continue;
- }
-
- while (true) {
- fd_set r, w, e;
- FD_ZERO(&r); FD_ZERO(&w); FD_ZERO(&e);
- FD_SET(nlc->s, &r);
- FD_SET(nlc->s, &w);
- FD_SET(nlc->s, &e);
- if ((rc = select(0, &r, &w, &e, &tv)) == SOCKET_ERROR)
- break;
-
- if (rc > 0) {
- if (FD_ISSET(nlc->s, &w)) {
- // connection was successful
- rc = 0;
- }
- if (FD_ISSET(nlc->s, &r)) {
- // connection was closed
- rc = SOCKET_ERROR;
- lasterr = WSAECONNRESET;
- }
- if (FD_ISSET(nlc->s, &e)) {
- // connection failed.
- int len = sizeof(lasterr);
- rc = SOCKET_ERROR;
- getsockopt(nlc->s, SOL_SOCKET, SO_ERROR, (char*)&lasterr, &len);
- if (lasterr == WSAEADDRINUSE && ++retrycnt <= 2) {
- closesocket(nlc->s);
- goto retry;
- }
- }
- break;
- }
- else if (Miranda_IsTerminated()) {
- rc = SOCKET_ERROR;
- lasterr = ERROR_TIMEOUT;
- break;
- }
- else if (nloc->flags & NLOCF_V2 && nloc->waitcallback != nullptr && nloc->waitcallback(&dwTimeout) == 0) {
- rc = SOCKET_ERROR;
- lasterr = ERROR_TIMEOUT;
- break;
- }
- if (--dwTimeout == 0) {
- rc = SOCKET_ERROR;
- lasterr = ERROR_TIMEOUT;
- break;
- }
- }
-
- if (rc == 0) break;
-
- closesocket(nlc->s);
- nlc->s = INVALID_SOCKET;
- }
-
- notblocking = 0;
- if (nlc->s != INVALID_SOCKET) ioctlsocket(nlc->s, FIONBIO, &notblocking);
- if (rc && lasterr) SetLastError(lasterr);
- return rc == 0;
-}
-
-static bool my_connectIPv6(NetlibConnection *nlc, NETLIBOPENCONNECTION *nloc)
-{
- if (!nloc)
- return false;
-
NetlibUser *nlu = nlc->nlu;
int rc = SOCKET_ERROR, retrycnt = 0;
u_long notblocking = 1;
uint32_t lasterr = 0;
static const TIMEVAL tv = { 1, 0 };
- unsigned int dwTimeout = (nloc->flags & NLOCF_V2) ? nloc->timeout : 0;
- // if dwTimeout is zero then its an old style connection or new with a 0 timeout, select() will error quicker anyway
- if (dwTimeout == 0) dwTimeout = 30;
+
+ // if timeout is zero then its an old style connection or new with a 0 timeout, select() will error quicker anyway
+ int timeout = (nlc->timeout <= 0) ? 30 : nlc->timeout;
// this is for XP SP2 where there is a default connection attempt limit of 10/second
if (connectionTimeout) {
@@ -505,8 +368,9 @@ static bool my_connectIPv6(NetlibConnection *nlc, NETLIBOPENCONNECTION *nloc)
g_LastConnectionTick = GetTickCount();
ReleaseMutex(hConnectionOpenMutex);
- // might of died in between the wait
- if (Miranda_IsTerminated()) return false;
+ // might have died in between the wait
+ if (Miranda_IsTerminated())
+ return false;
}
char szPort[6];
@@ -514,7 +378,8 @@ static bool my_connectIPv6(NetlibConnection *nlc, NETLIBOPENCONNECTION *nloc)
hints.ai_family = AF_UNSPEC;
- if (nloc->flags & NLOCF_UDP) {
+ NetlibUrl &url = nlc->url;
+ if (url.flags & NLOCF_UDP) {
hints.ai_socktype = SOCK_DGRAM;
hints.ai_protocol = IPPROTO_UDP;
}
@@ -527,7 +392,7 @@ static bool my_connectIPv6(NetlibConnection *nlc, NETLIBOPENCONNECTION *nloc)
if (!nlc->szProxyServer)
return false;
- Netlib_Logf(nlu, "(%p) Connecting to proxy %s:%d for %s:%d ....", nlc, nlc->szProxyServer, nlc->wProxyPort, nloc->szHost, nloc->wPort);
+ Netlib_Logf(nlu, "(%p) Connecting to proxy %s:%d for %s:%d ....", nlc, nlc->szProxyServer, nlc->wProxyPort, url.szHost.c_str(), url.port);
_itoa(nlc->wProxyPort, szPort, 10);
if (GetAddrInfoA(nlc->szProxyServer, szPort, &hints, &air)) {
@@ -536,15 +401,15 @@ static bool my_connectIPv6(NetlibConnection *nlc, NETLIBOPENCONNECTION *nloc)
}
}
else {
- if (!nloc->szHost)
+ if (url.szHost.IsEmpty())
return false;
- Netlib_Logf(nlu, "(%p) Connecting to server %s:%d....", nlc, nloc->szHost, nloc->wPort);
+ Netlib_Logf(nlu, "(%p) Connecting to server %s:%d....", nlc, url.szHost.c_str(), url.port);
- _itoa(nlc->nloc.wPort, szPort, 10);
+ _itoa(url.port, szPort, 10);
- if (GetAddrInfoA(nlc->nloc.szHost, szPort, &hints, &air)) {
- Netlib_Logf(nlu, "%s %d: %s() for host %s failed (%u)", __FILE__, __LINE__, "getaddrinfo", nlc->nloc.szHost, WSAGetLastError());
+ if (GetAddrInfoA(url.szHost, szPort, &hints, &air)) {
+ Netlib_Logf(nlu, "%s %d: %s() for host %s failed (%u)", __FILE__, __LINE__, "getaddrinfo", url.szHost.c_str(), WSAGetLastError());
return false;
}
}
@@ -623,12 +488,8 @@ retry:
lasterr = ERROR_TIMEOUT;
break;
}
- else if (nloc->flags & NLOCF_V2 && nloc->waitcallback != nullptr && nloc->waitcallback(&dwTimeout) == 0) {
- rc = SOCKET_ERROR;
- lasterr = ERROR_TIMEOUT;
- break;
- }
- if (--dwTimeout == 0) {
+
+ if (--timeout == 0) {
rc = SOCKET_ERROR;
lasterr = ERROR_TIMEOUT;
break;
@@ -649,17 +510,17 @@ retry:
return rc == 0;
}
-static int NetlibHttpFallbackToDirect(NetlibConnection *nlc, NetlibUser *nlu, NETLIBOPENCONNECTION *nloc)
+static int NetlibHttpFallbackToDirect(NetlibConnection *nlc)
{
NetlibDoCloseSocket(nlc, true);
- Netlib_Logf(nlu, "Fallback to direct connection");
+ Netlib_Logf(nlc->nlu, "Fallback to direct connection");
nlc->proxyAuthNeeded = false;
nlc->proxyType = 0;
replaceStr(nlc->szProxyServer, nullptr);
- if (!my_connectIPv6(nlc, nloc)) {
- Netlib_Logf(nlu, "%s %d: %s() failed (%u)", __FILE__, __LINE__, "connect", WSAGetLastError());
+ if (!my_connectIP(nlc)) {
+ Netlib_Logf(nlc->nlu, "%s %d: %s() failed (%u)", __FILE__, __LINE__, "connect", WSAGetLastError());
return false;
}
return true;
@@ -667,7 +528,6 @@ static int NetlibHttpFallbackToDirect(NetlibConnection *nlc, NetlibUser *nlu, NE
bool NetlibDoConnect(NetlibConnection *nlc)
{
- NETLIBOPENCONNECTION *nloc = &nlc->nloc;
NetlibUser *nlu = nlc->nlu;
replaceStr(nlc->szProxyServer, nullptr);
@@ -686,7 +546,7 @@ bool NetlibDoConnect(NetlibConnection *nlc)
}
}
- while (!my_connectIPv6(nlc, nloc)) {
+ while (!my_connectIP(nlc)) {
// if connection failed, the state of nlc might be unpredictable
if (GetNetlibHandleType(nlc) == NLH_CONNECTION) {
// Fallback to direct only when using HTTP proxy, as this is what used by companies
@@ -708,27 +568,27 @@ bool NetlibDoConnect(NetlibConnection *nlc)
return false;
}
- if (usingProxy && !((nloc->flags & (NLOCF_HTTP | NLOCF_SSL)) == NLOCF_HTTP && (nlc->proxyType == PROXYTYPE_HTTP || nlc->proxyType == PROXYTYPE_HTTPS))) {
+ if (usingProxy && !((nlc->url.flags & (NLOCF_HTTP | NLOCF_SSL)) == NLOCF_HTTP && (nlc->proxyType == PROXYTYPE_HTTP || nlc->proxyType == PROXYTYPE_HTTPS))) {
if (!WaitUntilWritable(nlc->s, 30000))
return false;
switch (nlc->proxyType) {
case PROXYTYPE_SOCKS4:
- if (!NetlibInitSocks4Connection(nlc, nlu, nloc))
+ if (!NetlibInitSocks4Connection(nlc))
return false;
break;
case PROXYTYPE_SOCKS5:
- if (!NetlibInitSocks5Connection(nlc, nlu, nloc))
+ if (!NetlibInitSocks5Connection(nlc))
return false;
break;
case PROXYTYPE_HTTPS:
case PROXYTYPE_HTTP:
nlc->proxyAuthNeeded = true;
- if (!NetlibInitHttpsConnection(nlc, nlu, nloc)) {
+ if (!NetlibInitHttpsConnection(nlc)) {
usingProxy = false;
- if (!NetlibHttpFallbackToDirect(nlc, nlu, nloc))
+ if (!NetlibHttpFallbackToDirect(nlc))
return false;
}
break;
@@ -740,7 +600,7 @@ bool NetlibDoConnect(NetlibConnection *nlc)
}
}
- Netlib_Logf(nlu, "(%d) Connected to %s:%d", nlc->s, nloc->szHost, nloc->wPort);
+ Netlib_Logf(nlu, "(%d) Connected to %s:%d", nlc->s, nlc->url.szHost.c_str(), nlc->url.port);
if (GetSubscribersCount((THook*)hEventConnected)) {
NETLIBCONNECTIONEVENTINFO ncei = {};
@@ -752,8 +612,8 @@ bool NetlibDoConnect(NetlibConnection *nlc)
size = sizeof(SOCKADDR_IN);
getpeername(nlc->s, (SOCKADDR *)&ncei.proxy, &size);
ncei.remote.sin_family = AF_INET;
- ncei.remote.sin_port = htons((short)nloc->wPort);
- ncei.remote.sin_addr.S_un.S_addr = DnsLookup(nlu, nloc->szHost);
+ ncei.remote.sin_port = htons(nlc->url.port);
+ ncei.remote.sin_addr.S_un.S_addr = DnsLookup(nlu, nlc->url.szHost);
}
else {
size = sizeof(SOCKADDR_IN);
@@ -762,7 +622,7 @@ bool NetlibDoConnect(NetlibConnection *nlc)
NotifyFastHook(hEventConnected, (WPARAM)&ncei, 0);
}
- if (NLOCF_SSL & nloc->flags)
+ if (NLOCF_SSL & nlc->url.flags)
return Netlib_StartSsl(nlc, nullptr) != 0;
return true;
@@ -804,10 +664,9 @@ bool NetlibReconnect(NetlibConnection *nlc)
return true;
}
-MIR_APP_DLL(HNETLIBCONN) Netlib_OpenConnection(NetlibUser *nlu, const NETLIBOPENCONNECTION *nloc)
+MIR_APP_DLL(HNETLIBCONN) Netlib_OpenConnection(NetlibUser *nlu, const char *szHost, int port, int timeout, int flags)
{
- if (nloc == nullptr || nloc->szHost == nullptr || nloc->wPort == 0) {
-
+ if (szHost == nullptr || port == 0) {
SetLastError(ERROR_INVALID_PARAMETER);
return nullptr;
}
@@ -815,12 +674,14 @@ MIR_APP_DLL(HNETLIBCONN) Netlib_OpenConnection(NetlibUser *nlu, const NETLIBOPEN
if (GetNetlibHandleType(nlu) != NLH_USER || !(nlu->user.flags & NUF_OUTGOING))
return nullptr;
- Netlib_Logf(nlu, "Connection request to %s:%d (Flags %x)....", nloc->szHost, nloc->wPort, nloc->flags);
+ Netlib_Logf(nlu, "Connection request to %s:%d (Flags %x)....", szHost, port, flags);
NetlibConnection *nlc = new NetlibConnection();
nlc->nlu = nlu;
- nlc->nloc = *nloc;
- nlc->nloc.szHost = mir_strdup(nloc->szHost);
+ nlc->timeout = timeout;
+ nlc->url.szHost = szHost;
+ nlc->url.port = port;
+ nlc->url.flags = flags;
nlc->dnsThroughProxy = nlu->settings.dnsThroughProxy != 0;
if (!NetlibDoConnect(nlc)) {
@@ -859,8 +720,6 @@ NetlibConnection::~NetlibConnection()
mir_free(nlhpi.szHttpPostUrl);
mir_free(nlhpi.szHttpGetUrl);
- mir_free((char*)nloc.szHost);
-
NetlibDeleteNestedCS(&ncsSend);
NetlibDeleteNestedCS(&ncsRecv);
diff --git a/src/mir_app/src/netlib_ssl.cpp b/src/mir_app/src/netlib_ssl.cpp
index a8048d753c..3874d978f4 100644
--- a/src/mir_app/src/netlib_ssl.cpp
+++ b/src/mir_app/src/netlib_ssl.cpp
@@ -363,7 +363,7 @@ MIR_APP_DLL(int) Netlib_StartSsl(HNETLIBCONN hConnection, const char *szHost)
NetlibUser *nlu = nlc->nlu;
if (szHost == nullptr)
- szHost = nlc->nloc.szHost;
+ szHost = nlc->url.szHost;
szHost = NEWSTR_ALLOCA(szHost);
Netlib_Logf(nlu, "(%d %s) Starting SSL/TLS negotiation", int(nlc->s), szHost);