source: filezilla/trunk/fuentes/src/engine/proxy.cpp @ 130

Last change on this file since 130 was 130, checked in by jrpelegrina, 4 years ago

First release to xenial

File size: 18.6 KB
Line 
1#include <filezilla.h>
2#include "engineprivate.h"
3#include "proxy.h"
4#include "ControlSocket.h"
5#include <wx/sckaddr.h>
6
7enum handshake_state
8{
9        http_wait,
10
11        socks5_method,
12        socks5_auth,
13        socks5_request,
14        socks5_request_addrtype,
15        socks5_request_address,
16
17        socks4_handshake
18};
19
20CProxySocket::CProxySocket(CEventHandler* pEvtHandler, CSocket* pSocket, CControlSocket* pOwner)
21        : CEventHandler(pOwner->event_loop_)
22        , CBackend(pEvtHandler)
23        , m_pSocket(pSocket)
24        , m_pOwner(pOwner)
25{
26        m_pSocket->SetEventHandler(this);
27}
28
29CProxySocket::~CProxySocket()
30{
31        RemoveHandler();
32
33        if (m_pSocket)
34                m_pSocket->SetEventHandler(0);
35        delete [] m_pSendBuffer;
36        delete [] m_pRecvBuffer;
37}
38
39namespace {
40wxString base64encode(const wxString& str)
41{
42        // Code shamelessly taken from wxWidgets and adopted to encode UTF-8 strings.
43        // wxWidget's http class encodes string from arbitrary encoding into base64,
44        // could as well encode /dev/random
45        static char const*const base64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
46
47        wxString buf;
48
49        const wxWX2MBbuf utf8 = str.mb_str(wxConvUTF8);
50        const char* from = utf8;
51
52        size_t len = strlen(from);
53        while (len >= 3) { // encode full blocks first
54                buf << wxString::Format(wxT("%c%c"), base64[(from[0] >> 2) & 0x3f], base64[((from[0] << 4) & 0x30) | ((from[1] >> 4) & 0xf)]);
55                buf << wxString::Format(wxT("%c%c"), base64[((from[1] << 2) & 0x3c) | ((from[2] >> 6) & 0x3)], base64[from[2] & 0x3f]);
56                from += 3;
57                len -= 3;
58        }
59        if (len > 0) { // pad the remaining characters
60                buf << wxString::Format(wxT("%c"), base64[(from[0] >> 2) & 0x3f]);
61                if (len == 1) {
62                        buf << wxString::Format(wxT("%c="), base64[(from[0] << 4) & 0x30]);
63                }
64                else {
65                        buf << wxString::Format(wxT("%c%c"), base64[((from[0] << 4) & 0x30) | ((from[1] >> 4) & 0xf)], base64[(from[1] << 2) & 0x3c]);
66                }
67                buf << wxString::Format(wxT("="));
68        }
69
70        return buf;
71}
72}
73
74wxString CProxySocket::Name(ProxyType t)
75{
76        switch (t) {
77        case HTTP:
78                return _T("HTTP");
79        case SOCKS4:
80                return _T("SOCKS4");
81        case SOCKS5:
82                return _T("SOCKS5");
83        default:
84                return _("unknown");
85        }
86}
87
88int CProxySocket::Handshake(CProxySocket::ProxyType type, const wxString& host, unsigned int port, const wxString& user, const wxString& pass)
89{
90        if (type == CProxySocket::unknown || host.empty() || port < 1 || port > 65535)
91                return EINVAL;
92
93        if (m_proxyState != noconn)
94                return EALREADY;
95
96        const wxWX2MBbuf host_raw = host.mb_str(wxConvUTF8);
97
98        if (type != HTTP && type != SOCKS5 && type != SOCKS4)
99                return EPROTONOSUPPORT;
100
101        m_user = user;
102        m_pass = pass;
103        m_host = host;
104        m_port = port;
105        m_proxyType = type;
106
107        m_proxyState = handshake;
108
109        if (type == HTTP) {
110                m_handshakeState = http_wait;
111
112                wxWX2MBbuf challenge{};
113                int challenge_len{};
114                if (!user.empty()) {
115                        challenge = base64encode(user + _T(":") + pass).mb_str(wxConvUTF8);
116                        challenge_len = strlen(challenge);
117                }
118
119                // Bit oversized, but be on the safe side
120                m_pSendBuffer = new char[70 + strlen(host_raw) * 2 + 2*5 + challenge_len + 23];
121
122                if (!challenge || !challenge_len) {
123                        m_sendBufferLen = sprintf(m_pSendBuffer, "CONNECT %s:%u HTTP/1.1\r\nHost: %s:%u\r\nUser-Agent: FileZilla\r\n\r\n",
124                                (const char*)host_raw, port,
125                                (const char*)host_raw, port);
126                }
127                else {
128                        m_sendBufferLen = sprintf(m_pSendBuffer, "CONNECT %s:%u HTTP/1.1\r\nHost: %s:%u\r\nProxy-Authorization: Basic %s\r\nUser-Agent: FileZilla\r\n\r\n",
129                                (const char*)host_raw, port,
130                                (const char*)host_raw, port,
131                                (const char*)challenge);
132                }
133
134                m_pRecvBuffer = new char[4096];
135                m_recvBufferLen = 4096;
136                m_recvBufferPos = 0;
137        }
138        else if (type == SOCKS4) {
139                wxString ip = m_host;
140                if (!GetIPV6LongForm(m_host).empty()) {
141                        m_pOwner->LogMessage(MessageType::Error, _("IPv6 addresses are not supported with SOCKS4 proxy"));
142                        return EINVAL;
143                }
144
145                if (!IsIpAddress(m_host)) {
146                        wxIPV4address address;
147                        if (!address.Hostname(host)) {
148                                m_pOwner->LogMessage(MessageType::Error, _("Cannot resolve hostname to IPv4 address for use with SOCKS4 proxy."));
149                                return EINVAL;
150                        }
151                        ip = address.IPAddress();
152                }
153
154                m_pOwner->LogMessage(MessageType::Status, _("SOCKS4 proxy will connect to: %s"), ip);
155
156                m_pSendBuffer = new char[9];
157                m_pSendBuffer[0] = 4; // Protocol version
158                m_pSendBuffer[1] = 1; // Stream mode
159                m_pSendBuffer[2] = (m_port >> 8) & 0xFF; // Port in network order
160                m_pSendBuffer[3] = m_port & 0xFF;
161                unsigned char *buf = (unsigned char*)m_pSendBuffer + 4;
162                int i = 0;
163                memset(buf, 0, 4);
164                for (const wxChar* p = ip.c_str(); *p && i < 4; p++) {
165                        const wxChar& c = *p;
166                        if (c == '.') {
167                                i++;
168                                continue;
169                        }
170                        buf[i] *= 10;
171                        buf[i] += c - '0';
172                }
173                m_pSendBuffer[8] = 0;
174                m_sendBufferLen = 9;
175                m_pRecvBuffer = new char[8];
176                m_recvBufferLen = 8;
177                m_recvBufferPos = 0;
178                m_handshakeState = socks4_handshake;
179        }
180        else {
181                m_pSendBuffer = new char[4];
182                m_pSendBuffer[0] = 5; // Protocol version
183                if (!user.empty()) {
184                        m_pSendBuffer[1] = 2; // # auth methods supported
185                        m_pSendBuffer[2] = 0; // Method: No auth
186                        m_pSendBuffer[3] = 2; // Method: Username and password
187                        m_sendBufferLen = 4;
188                }
189                else {
190                        m_pSendBuffer[1] = 1; // # auth methods supported
191                        m_pSendBuffer[2] = 0; // Method: No auth
192                        m_sendBufferLen = 3;
193                }
194
195                m_pRecvBuffer = new char[1024];
196                m_recvBufferLen = 2;
197                m_recvBufferPos = 0;
198
199                m_handshakeState = socks5_method;
200        }
201
202        return EINPROGRESS;
203}
204
205void CProxySocket::operator()(CEventBase const& ev)
206{
207        Dispatch<CSocketEvent, CHostAddressEvent>(ev, this,
208                &CProxySocket::OnSocketEvent,
209                &CProxySocket::OnHostAddress);
210}
211
212void CProxySocket::OnSocketEvent(CSocketEventSource*, SocketEventType t, int error)
213{
214        switch (t) {
215        case SocketEventType::connection_next:
216                if (error)
217                        m_pOwner->LogMessage(MessageType::Status, _("Connection attempt failed with \"%s\", trying next address."), CSocket::GetErrorDescription(error));
218                break;
219        case SocketEventType::connection:
220                if (error) {
221                        if (m_proxyState == handshake)
222                                m_proxyState = noconn;
223                        m_pEvtHandler->SendEvent<CSocketEvent>(this, SocketEventType::connection, error);
224                }
225                else {
226                        m_pOwner->LogMessage(MessageType::Status, _("Connection with proxy established, performing handshake..."));
227                }
228                break;
229        case SocketEventType::read:
230                OnReceive();
231                break;
232        case SocketEventType::write:
233                OnSend();
234                break;
235        case SocketEventType::close:
236                OnReceive();
237                break;
238        }
239}
240
241void CProxySocket::OnHostAddress(CSocketEventSource*, wxString const& address)
242{
243        m_pOwner->LogMessage(MessageType::Status, _("Connecting to %s..."), address);
244}
245
246void CProxySocket::Detach()
247{
248        if (!m_pSocket)
249                return;
250
251        m_pSocket->SetEventHandler(0);
252        m_pSocket = 0;
253}
254
255void CProxySocket::OnReceive()
256{
257        m_can_read = true;
258
259        if (m_proxyState != handshake)
260                return;
261
262        switch (m_handshakeState)
263        {
264        case http_wait:
265                for (;;) {
266                        int error;
267                        int do_read = m_recvBufferLen - m_recvBufferPos - 1;
268                        char* end = 0;
269                        for (int i = 0; i < 2; ++i) {
270                                int read;
271                                if (!i)
272                                        read = m_pSocket->Peek(m_pRecvBuffer + m_recvBufferPos, do_read, error);
273                                else
274                                        read = m_pSocket->Read(m_pRecvBuffer + m_recvBufferPos, do_read, error);
275                                if (read == -1) {
276                                        if (error != EAGAIN) {
277                                                m_proxyState = noconn;
278                                                m_pEvtHandler->SendEvent<CSocketEvent>(this, SocketEventType::close, error);
279                                        }
280                                        else
281                                                m_can_read = false;
282                                        return;
283                                }
284                                if (!read) {
285                                        m_proxyState = noconn;
286                                        m_pEvtHandler->SendEvent<CSocketEvent>(this, SocketEventType::close, ECONNABORTED);
287                                        return;
288                                }
289                                if (m_pSendBuffer) {
290                                        m_proxyState = noconn;
291                                        m_pOwner->LogMessage(MessageType::Debug_Warning, _T("Incoming data before request fully sent"));
292                                        m_pEvtHandler->SendEvent<CSocketEvent>(this, SocketEventType::close, ECONNABORTED);
293                                        return;
294                                }
295
296                                if (!i) {
297                                        // Response ends with strstr
298                                        m_pRecvBuffer[m_recvBufferPos + read] = 0;
299                                        end = strstr(m_pRecvBuffer, "\r\n\r\n");
300                                        if (!end) {
301                                                if (m_recvBufferPos + read + 1 == m_recvBufferLen) {
302                                                        m_proxyState = noconn;
303                                                        m_pOwner->LogMessage(MessageType::Debug_Warning, _T("Incoming header too large"));
304                                                        m_pEvtHandler->SendEvent<CSocketEvent>(this, SocketEventType::close, ENOMEM);
305                                                        return;
306                                                }
307                                                do_read = read;
308                                        }
309                                        else
310                                                do_read = end - m_pRecvBuffer + 4 - m_recvBufferPos;
311                                }
312                                else {
313                                        if (read != do_read) {
314                                                m_proxyState = noconn;
315                                                m_pOwner->LogMessage(MessageType::Debug_Warning, _T("Could not read what got peeked"));
316                                                m_pEvtHandler->SendEvent<CSocketEvent>(this, SocketEventType::close, ECONNABORTED);
317                                                return;
318                                        }
319                                        m_recvBufferPos += read;
320                                }
321                        }
322
323                        if (!end)
324                                continue;
325
326                        end = strchr(m_pRecvBuffer, '\r'); // Never fails as old value of end exists and starts with CR, we just look for an earlier case.
327                        *end = 0;
328                        wxString reply(m_pRecvBuffer, wxConvUTF8);
329                        m_pOwner->LogMessage(MessageType::Response, _("Proxy reply: %s"), reply);
330
331                        if (reply.Left(10) != _T("HTTP/1.1 2") && reply.Left(10) != _T("HTTP/1.0 2")) {
332                                m_proxyState = noconn;
333                                m_pEvtHandler->SendEvent<CSocketEvent>(this, SocketEventType::close, ECONNRESET);
334                                return;
335                        }
336
337                        m_proxyState = conn;
338                        m_pEvtHandler->SendEvent<CSocketEvent>(this, SocketEventType::connection, 0);
339                        return;
340                }
341        case socks4_handshake:
342                while (m_recvBufferLen && m_can_read && m_proxyState == handshake) {
343                        int read_error;
344                        int read = m_pSocket->Read(m_pRecvBuffer + m_recvBufferPos, m_recvBufferLen, read_error);
345                        if (read == -1) {
346                                if (read_error != EAGAIN) {
347                                        m_proxyState = noconn;
348                                        m_pEvtHandler->SendEvent<CSocketEvent>(this, SocketEventType::close, read_error);
349                                }
350                                else
351                                        m_can_read = false;
352                                return;
353                        }
354
355                        if (!read) {
356                                m_proxyState = noconn;
357                                m_pEvtHandler->SendEvent<CSocketEvent>(this, SocketEventType::close, ECONNABORTED);
358                                return;
359                        }
360                        m_recvBufferPos += read;
361                        m_recvBufferLen -= read;
362
363                        if (m_recvBufferLen)
364                                continue;
365
366                        m_recvBufferPos = 0;
367
368                        if (m_pRecvBuffer[1] != 0x5A) {
369                                wxString error;
370                                switch (m_pRecvBuffer[1]) {
371                                        case 0x5B:
372                                                error = _("Request rejected or failed");
373                                                break;
374                                        case 0x5C:
375                                                error = _("Request failed - client is not running identd (or not reachable from server)");
376                                                break;
377                                        case 0x5D:
378                                                error = _("Request failed - client's identd could not confirm the user ID string");
379                                                break;
380                                        default:
381                                                error.Printf(_("Unassigned error code %d"), (int)(unsigned char) m_pRecvBuffer[1]);
382                                                break;
383                                }
384                                m_pOwner->LogMessage(MessageType::Error, _("Proxy request failed: %s"), error);
385                                m_proxyState = noconn;
386                                m_pEvtHandler->SendEvent<CSocketEvent>(this, SocketEventType::close, ECONNABORTED);
387                                return;
388                        }
389                        m_proxyState = conn;
390                        m_pEvtHandler->SendEvent<CSocketEvent>(this, SocketEventType::connection, 0);
391                }
392                return;
393        case socks5_method:
394        case socks5_auth:
395        case socks5_request:
396        case socks5_request_addrtype:
397        case socks5_request_address:
398                if (m_pSendBuffer)
399                        return;
400                while (m_recvBufferLen && m_can_read && m_proxyState == handshake) {
401                        int error;
402                        int read = m_pSocket->Read(m_pRecvBuffer + m_recvBufferPos, m_recvBufferLen, error);
403                        if (read == -1) {
404                                if (error != EAGAIN) {
405                                        m_proxyState = noconn;
406                                        m_pEvtHandler->SendEvent<CSocketEvent>(this, SocketEventType::close, error);
407                                }
408                                else
409                                        m_can_read = false;
410                                return;
411                        }
412                        if (!read) {
413                                m_proxyState = noconn;
414                                m_pEvtHandler->SendEvent<CSocketEvent>(this, SocketEventType::close, ECONNABORTED);
415                                return;
416                        }
417                        m_recvBufferPos += read;
418                        m_recvBufferLen -= read;
419
420                        if (m_recvBufferLen)
421                                continue;
422
423                        m_recvBufferPos = 0;
424
425                        // All data got read, parse it
426                        switch (m_handshakeState) {
427                        default:
428                                if (m_pRecvBuffer[0] != 5) {
429                                        m_pOwner->LogMessage(MessageType::Debug_Warning, _("Unknown SOCKS protocol version: %d"), (int)m_pRecvBuffer[0]);
430                                        m_proxyState = noconn;
431                                        m_pEvtHandler->SendEvent<CSocketEvent>(this, SocketEventType::close, ECONNABORTED);
432                                        return;
433                                }
434                                break;
435                        case socks5_auth:
436                                if (m_pRecvBuffer[0] != 1) {
437                                        m_pOwner->LogMessage(MessageType::Debug_Warning, _("Unknown protocol version of SOCKS Username/Password Authentication subnegotiation: %d"), (int)m_pRecvBuffer[0]);
438                                        m_proxyState = noconn;
439                                        m_pEvtHandler->SendEvent<CSocketEvent>(this, SocketEventType::close, ECONNABORTED);
440                                        return;
441                                }
442                                break;
443                        case socks5_request_address:
444                        case socks5_request_addrtype:
445                                // Nothing to do
446                                break;
447                        }
448                        switch (m_handshakeState) {
449                        case socks5_method:
450                                {
451                                        const char method = m_pRecvBuffer[1];
452                                        switch (method)
453                                        {
454                                        case 0:
455                                                m_handshakeState = socks5_request;
456                                                break;
457                                        case 2:
458                                                m_handshakeState = socks5_auth;
459                                                break;
460                                        default:
461                                                m_pOwner->LogMessage(MessageType::Debug_Warning, _("No supported SOCKS5 auth method"));
462                                                m_proxyState = noconn;
463                                                m_pEvtHandler->SendEvent<CSocketEvent>(this, SocketEventType::close, ECONNABORTED);
464                                                return;
465                                        }
466                                }
467                                break;
468                        case socks5_auth:
469                                if (m_pRecvBuffer[1] != 0)
470                                {
471                                        m_pOwner->LogMessage(MessageType::Debug_Warning, _("Proxy authentication failed"));
472                                        m_proxyState = noconn;
473                                        m_pEvtHandler->SendEvent<CSocketEvent>(this, SocketEventType::close, ECONNABORTED);
474                                        return;
475                                }
476                                m_handshakeState = socks5_request;
477                                break;
478                        case socks5_request:
479                                if (m_pRecvBuffer[1]) {
480                                        wxString errorMsg;
481                                        switch (m_pRecvBuffer[1])
482                                        {
483                                        case 1:
484                                                errorMsg = _("General SOCKS server failure");
485                                                break;
486                                        case 2:
487                                                errorMsg = _("Connection not allowed by ruleset");
488                                                break;
489                                        case 3:
490                                                errorMsg = _("Network unreachable");
491                                                break;
492                                        case 4:
493                                                errorMsg = _("Host unreachable");
494                                                break;
495                                        case 5:
496                                                errorMsg = _("Connection refused");
497                                                break;
498                                        case 6:
499                                                errorMsg = _("TTL expired");
500                                                break;
501                                        case 7:
502                                                errorMsg = _("Command not supported");
503                                                break;
504                                        case 8:
505                                                errorMsg = _("Address type not supported");
506                                                break;
507                                        default:
508                                                errorMsg.Printf(_("Unassigned error code %d"), (int)(unsigned char)m_pRecvBuffer[1]);
509                                                break;
510                                        }
511
512                                        m_pOwner->LogMessage(MessageType::Debug_Warning, _("Proxy request failed: %s"), errorMsg);
513                                        m_proxyState = noconn;
514                                        m_pEvtHandler->SendEvent<CSocketEvent>(this, SocketEventType::close, ECONNABORTED);
515                                        return;
516                                }
517                                m_handshakeState = socks5_request_addrtype;
518                                m_recvBufferLen = 3;
519                                break;
520                        case socks5_request_addrtype:
521                                // We need to parse the returned address type to determine the length of the address that follows.
522                                // Unfortunately the information in the type and address is useless, many proxies just return
523                                // syntactically valid bogus values
524                                switch (m_pRecvBuffer[1])
525                                {
526                                case 1:
527                                        m_recvBufferLen = 5;
528                                        break;
529                                case 3:
530                                        m_recvBufferLen = m_pRecvBuffer[2] + 2;
531                                        break;
532                                case 4:
533                                        m_recvBufferLen = 17;
534                                        break;
535                                default:
536                                        m_pOwner->LogMessage(MessageType::Debug_Warning, _("Proxy request failed: Unknown address type in CONNECT reply"));
537                                        m_proxyState = noconn;
538                                        m_pEvtHandler->SendEvent<CSocketEvent>(this, SocketEventType::close, ECONNABORTED);
539                                        return;
540                                }
541                                m_handshakeState = socks5_request_address;
542                                break;
543                        case socks5_request_address:
544                                {
545                                        // We're done
546                                        m_proxyState = conn;
547                                        m_pEvtHandler->SendEvent<CSocketEvent>(this, SocketEventType::connection, 0);
548                                        return;
549                                }
550                        default:
551                                wxFAIL;
552                                break;
553                        }
554
555                        switch (m_handshakeState)
556                        {
557                        case socks5_auth:
558                                {
559                                        const wxWX2MBbuf user = m_user.mb_str(wxConvUTF8);
560                                        const wxWX2MBbuf pass = m_pass.mb_str(wxConvUTF8);
561
562                                        const int userlen = strlen(user);
563                                        const int passlen = strlen(pass);
564                                        m_sendBufferLen = userlen + passlen + 3;
565                                        m_pSendBuffer = new char[m_sendBufferLen];
566                                        m_pSendBuffer[0] = 1;
567                                        m_pSendBuffer[1] = userlen;
568                                        memcpy(m_pSendBuffer + 2, (const char*)user, userlen);
569                                        m_pSendBuffer[userlen + 2] = passlen;
570                                        memcpy(m_pSendBuffer + userlen + 3, (const char*)pass, passlen);
571                                        m_recvBufferLen = 2;
572                                }
573                                break;
574                        case socks5_request:
575                                {
576                                        const wxWX2MBbuf host = m_host.mb_str(wxConvUTF8);
577                                        const int hostlen = strlen(host);
578                                        int addrlen = wxMax(hostlen, 16);
579
580                                        m_pSendBuffer = new char[7 + addrlen];
581                                        m_pSendBuffer[0] = 5;
582                                        m_pSendBuffer[1] = 1; // CONNECT
583                                        m_pSendBuffer[2] = 0; // Reserved
584
585                                        if (IsIpAddress(m_host)) {
586                                                // Quite ugly
587                                                wxString ipv6 = GetIPV6LongForm(m_host);
588                                                if (!ipv6.empty()) {
589                                                        ipv6.Replace(_T(":"), _T(""));
590                                                        addrlen = 16;
591                                                        for (int i = 0; i < 16; i++)
592                                                                m_pSendBuffer[4 + i] = (DigitHexToDecNum(ipv6[i * 2]) << 4) + DigitHexToDecNum(ipv6[i * 2 + 1]);
593
594                                                        m_pSendBuffer[3] = 4; // IPv6
595                                                }
596                                                else {
597                                                        unsigned char *buf = (unsigned char*)m_pSendBuffer + 4;
598                                                        int i = 0;
599                                                        memset(buf, 0, 4);
600                                                        for (const wxChar* p = m_host.c_str(); *p && i < 4; p++)
601                                                        {
602                                                                const wxChar& c = *p;
603                                                                if (c == '.')
604                                                                {
605                                                                        i++;
606                                                                        continue;
607                                                                }
608                                                                buf[i] *= 10;
609                                                                buf[i] += c - '0';
610                                                        }
611
612                                                        addrlen = 4;
613
614                                                        m_pSendBuffer[3] = 1; // IPv4
615                                                }
616                                        }
617                                        else {
618                                                m_pSendBuffer[3] = 3; // Domain name
619                                                m_pSendBuffer[4] = hostlen;
620                                                memcpy(m_pSendBuffer + 5, (const char*)host, hostlen);
621                                                addrlen = hostlen + 1;
622                                        }
623
624
625                                        m_pSendBuffer[addrlen + 4] = (m_port >> 8) & 0xFF; // Port in network order
626                                        m_pSendBuffer[addrlen + 5] = m_port & 0xFF;
627
628                                        m_sendBufferLen = 6 + addrlen;
629                                        m_recvBufferLen = 2;
630                                }
631                                break;
632                        case socks5_request_addrtype:
633                        case socks5_request_address:
634                                // Nothing to send, we simply need to wait for more data
635                                break;
636                        default:
637                                wxFAIL;
638                                break;
639                        }
640                        if (m_pSendBuffer && m_can_write)
641                                OnSend();
642                }
643                break;
644        default:
645                m_proxyState = noconn;
646                m_pOwner->LogMessage(MessageType::Debug_Warning, _T("Unhandled handshake state %d"), m_handshakeState);
647                m_pEvtHandler->SendEvent<CSocketEvent>(this, SocketEventType::close, ECONNABORTED);
648                return;
649        }
650}
651
652void CProxySocket::OnSend()
653{
654        m_can_write = true;
655        if (m_proxyState != handshake || !m_pSendBuffer)
656                return;
657
658        for (;;) {
659                int error;
660                int written = m_pSocket->Write(m_pSendBuffer, m_sendBufferLen, error);
661                if (written == -1) {
662                        if (error != EAGAIN) {
663                                m_proxyState = noconn;
664                                m_pEvtHandler->SendEvent<CSocketEvent>(this, SocketEventType::close, error);
665                        }
666                        else
667                                m_can_write = false;
668
669                        return;
670                }
671
672                if (written == m_sendBufferLen) {
673                        delete [] m_pSendBuffer;
674                        m_pSendBuffer = 0;
675
676                        if (m_can_read)
677                                OnReceive();
678                        return;
679                }
680                memmove(m_pSendBuffer, m_pSendBuffer + written, m_sendBufferLen - written);
681                m_sendBufferLen -= written;
682        }
683}
684
685int CProxySocket::Read(void *, unsigned int, int& error)
686{
687        error = EAGAIN;
688        return -1;
689}
690
691int CProxySocket::Peek(void *, unsigned int, int& error)
692{
693        error = EAGAIN;
694        return -1;
695}
696
697int CProxySocket::Write(const void *, unsigned int, int& error)
698{
699        error = EAGAIN;
700        return -1;
701}
Note: See TracBrowser for help on using the repository browser.