From c4ffab658f422e84259a0a9769f0003b33a013bd Mon Sep 17 00:00:00 2001 From: George Hazan Date: Sat, 7 May 2022 15:00:02 +0300 Subject: Netlib_OpenConnection - finally old stupid structure NETLIBOPENCONNECTION died and converted into a set of parameters + code cleaning --- include/m_netlib.h | 14 +- libs/win32/mir_app.lib | Bin 225554 -> 225562 bytes libs/win64/mir_app.lib | Bin 221278 -> 221278 bytes plugins/CrashDumper/src/crshdmp.cpp | 2 +- plugins/Ping/src/utils.cpp | 9 +- plugins/Watrack_MPD/src/main.cpp | 8 +- protocols/Facebook/src/server.cpp | 6 +- protocols/IRCG/src/irclib.cpp | 19 +- protocols/JabberG/jabber.vcxproj | 1 - protocols/JabberG/jabber.vcxproj.filters | 3 - protocols/JabberG/src/jabber_byte.cpp | 16 +- protocols/JabberG/src/jabber_file.cpp | 7 +- protocols/JabberG/src/jabber_proto.cpp | 8 +- protocols/JabberG/src/jabber_proto.h | 13 +- protocols/JabberG/src/jabber_thread.cpp | 48 ++--- protocols/JabberG/src/jabber_ws.cpp | 72 -------- protocols/JabberG/src/jabber_zstream.cpp | 8 +- protocols/JabberG/src/stdafx.h | 4 +- protocols/Sametime/src/sametime_session.cpp | 14 +- protocols/YAMN/src/proto/netlib.cpp | 5 +- src/mir_app/src/mir_app.def | 1 + src/mir_app/src/mir_app64.def | 1 + src/mir_app/src/netlib.h | 9 +- src/mir_app/src/netlib_autoproxy.cpp | 10 +- src/mir_app/src/netlib_http.cpp | 36 ++-- src/mir_app/src/netlib_openconn.cpp | 269 +++++++--------------------- src/mir_app/src/netlib_ssl.cpp | 2 +- 27 files changed, 156 insertions(+), 429 deletions(-) delete mode 100644 protocols/JabberG/src/jabber_ws.cpp 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 Binary files a/libs/win32/mir_app.lib and b/libs/win32/mir_app.lib differ diff --git a/libs/win64/mir_app.lib b/libs/win64/mir_app.lib index 6357328d82..870add873d 100644 Binary files a/libs/win64/mir_app.lib and b/libs/win64/mir_app.lib 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 @@ - 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 @@ Source Files - - Source Files - Source Files 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, public IJabberInterface { + friend struct ThreadData; + class CJabberProtoImpl { friend struct CJabberProto; @@ -240,6 +242,7 @@ struct CJabberProto : public PROTO, public IJabberInterface CMOption m_iConnectionKeepAliveTimeout; PVOID m_sslCtx; + mir_cs m_csSocket; // protects i/o operations HANDLE m_hThreadHandle; @@ -883,14 +886,6 @@ struct CJabberProto : public PROTO, 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, 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, "\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, ¬blocking) != 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, ¬blocking); - 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); -- cgit v1.2.3