1f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org/* 2f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org * Copyright 2004 The WebRTC Project Authors. All rights reserved. 3f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org * 4f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org * Use of this source code is governed by a BSD-style license 5f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org * that can be found in the LICENSE file in the root of the source 6f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org * tree. An additional intellectual property rights grant can be found 7f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org * in the file PATENTS. All contributing project authors may 8f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org * be found in the AUTHORS file in the root of the source tree. 9f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org */ 10f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 11f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#if defined(_MSC_VER) && _MSC_VER < 1300 12f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#pragma warning(disable:4786) 13f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#endif 14f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 15f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include <time.h> 16f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include <errno.h> 17f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 18f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#if defined(WEBRTC_WIN) 19f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#define WIN32_LEAN_AND_MEAN 20f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include <windows.h> 21f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include <winsock2.h> 22f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include <ws2tcpip.h> 23f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#define SECURITY_WIN32 24f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include <security.h> 25f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#endif 26f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 27ff689be3c0c59c1be29aaa0697aa0f762566d6c6andresp@webrtc.org#include <algorithm> 28ff689be3c0c59c1be29aaa0697aa0f762566d6c6andresp@webrtc.org 29f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include "webrtc/base/bytebuffer.h" 30f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include "webrtc/base/common.h" 31f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include "webrtc/base/httpcommon.h" 32f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include "webrtc/base/logging.h" 33f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include "webrtc/base/socketadapters.h" 34f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include "webrtc/base/stringencode.h" 35f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include "webrtc/base/stringutils.h" 36f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 37f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#if defined(WEBRTC_WIN) 38f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include "webrtc/base/sec_buffer.h" 39f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#endif // WEBRTC_WIN 40f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 41f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgnamespace rtc { 42f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 43f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgBufferedReadAdapter::BufferedReadAdapter(AsyncSocket* socket, size_t size) 44f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org : AsyncSocketAdapter(socket), buffer_size_(size), 45f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org data_len_(0), buffering_(false) { 46f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org buffer_ = new char[buffer_size_]; 47f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 48f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 49f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgBufferedReadAdapter::~BufferedReadAdapter() { 50f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org delete [] buffer_; 51f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 52f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 53f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgint BufferedReadAdapter::Send(const void *pv, size_t cb) { 54f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (buffering_) { 55f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // TODO: Spoof error better; Signal Writeable 56f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org socket_->SetError(EWOULDBLOCK); 57f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return -1; 58f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 59f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return AsyncSocketAdapter::Send(pv, cb); 60f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 61f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 62f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgint BufferedReadAdapter::Recv(void *pv, size_t cb) { 63f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (buffering_) { 64f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org socket_->SetError(EWOULDBLOCK); 65f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return -1; 66f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 67f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 68f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org size_t read = 0; 69f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 70f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (data_len_) { 71ff689be3c0c59c1be29aaa0697aa0f762566d6c6andresp@webrtc.org read = std::min(cb, data_len_); 72f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org memcpy(pv, buffer_, read); 73f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org data_len_ -= read; 74f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (data_len_ > 0) { 75f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org memmove(buffer_, buffer_ + read, data_len_); 76f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 77f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org pv = static_cast<char *>(pv) + read; 78f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org cb -= read; 79f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 80f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 81f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // FIX: If cb == 0, we won't generate another read event 82f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 83f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org int res = AsyncSocketAdapter::Recv(pv, cb); 84c5d0d95fd8957a7a6645b1196e5f1e9cee33525cdeadbeef if (res >= 0) { 85c5d0d95fd8957a7a6645b1196e5f1e9cee33525cdeadbeef // Read from socket and possibly buffer; return combined length 86c5d0d95fd8957a7a6645b1196e5f1e9cee33525cdeadbeef return res + static_cast<int>(read); 87c5d0d95fd8957a7a6645b1196e5f1e9cee33525cdeadbeef } 88c5d0d95fd8957a7a6645b1196e5f1e9cee33525cdeadbeef 89c5d0d95fd8957a7a6645b1196e5f1e9cee33525cdeadbeef if (read > 0) { 90c5d0d95fd8957a7a6645b1196e5f1e9cee33525cdeadbeef // Failed to read from socket, but still read something from buffer 91c5d0d95fd8957a7a6645b1196e5f1e9cee33525cdeadbeef return static_cast<int>(read); 92c5d0d95fd8957a7a6645b1196e5f1e9cee33525cdeadbeef } 93f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 94c5d0d95fd8957a7a6645b1196e5f1e9cee33525cdeadbeef // Didn't read anything; return error from socket 95c5d0d95fd8957a7a6645b1196e5f1e9cee33525cdeadbeef return res; 96f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 97f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 98f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid BufferedReadAdapter::BufferInput(bool on) { 99f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org buffering_ = on; 100f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 101f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 102f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid BufferedReadAdapter::OnReadEvent(AsyncSocket * socket) { 103f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org ASSERT(socket == socket_); 104f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 105f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (!buffering_) { 106f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org AsyncSocketAdapter::OnReadEvent(socket); 107f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return; 108f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 109f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 110f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (data_len_ >= buffer_size_) { 111f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org LOG(INFO) << "Input buffer overflow"; 112f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org ASSERT(false); 113f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org data_len_ = 0; 114f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 115f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 116f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org int len = socket_->Recv(buffer_ + data_len_, buffer_size_ - data_len_); 117f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (len < 0) { 118f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // TODO: Do something better like forwarding the error to the user. 119f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org LOG_ERR(INFO) << "Recv"; 120f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return; 121f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 122f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 123f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org data_len_ += len; 124f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 125f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org ProcessInput(buffer_, &data_len_); 126f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 127f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 12867186fe00cc68cbe03aa66d17fb4962458ca96d2kwiberg@webrtc.orgAsyncProxyServerSocket::AsyncProxyServerSocket(AsyncSocket* socket, 12967186fe00cc68cbe03aa66d17fb4962458ca96d2kwiberg@webrtc.org size_t buffer_size) 13067186fe00cc68cbe03aa66d17fb4962458ca96d2kwiberg@webrtc.org : BufferedReadAdapter(socket, buffer_size) { 13167186fe00cc68cbe03aa66d17fb4962458ca96d2kwiberg@webrtc.org} 13267186fe00cc68cbe03aa66d17fb4962458ca96d2kwiberg@webrtc.org 13367186fe00cc68cbe03aa66d17fb4962458ca96d2kwiberg@webrtc.orgAsyncProxyServerSocket::~AsyncProxyServerSocket() = default; 13467186fe00cc68cbe03aa66d17fb4962458ca96d2kwiberg@webrtc.org 135f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org/////////////////////////////////////////////////////////////////////////////// 136f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 137f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// This is a SSL v2 CLIENT_HELLO message. 138f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// TODO: Should this have a session id? The response doesn't have a 139f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// certificate, so the hello should have a session id. 1400c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boströmstatic const uint8_t kSslClientHello[] = { 1410c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström 0x80, 0x46, // msg len 1420c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström 0x01, // CLIENT_HELLO 1430c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström 0x03, 0x01, // SSL 3.1 1440c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström 0x00, 0x2d, // ciphersuite len 1450c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström 0x00, 0x00, // session id len 1460c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström 0x00, 0x10, // challenge len 1470c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström 0x01, 0x00, 0x80, 0x03, 0x00, 0x80, 0x07, 0x00, 0xc0, // ciphersuites 1480c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström 0x06, 0x00, 0x40, 0x02, 0x00, 0x80, 0x04, 0x00, 0x80, // 1490c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström 0x00, 0x00, 0x04, 0x00, 0xfe, 0xff, 0x00, 0x00, 0x0a, // 1500c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström 0x00, 0xfe, 0xfe, 0x00, 0x00, 0x09, 0x00, 0x00, 0x64, // 1510c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström 0x00, 0x00, 0x62, 0x00, 0x00, 0x03, 0x00, 0x00, 0x06, // 1520c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström 0x1f, 0x17, 0x0c, 0xa6, 0x2f, 0x00, 0x78, 0xfc, // challenge 1530c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström 0x46, 0x55, 0x2e, 0xb1, 0x83, 0x39, 0xf1, 0xea // 154f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}; 155f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 156f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// This is a TLSv1 SERVER_HELLO message. 1570c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boströmstatic const uint8_t kSslServerHello[] = { 1580c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström 0x16, // handshake message 1590c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström 0x03, 0x01, // SSL 3.1 1600c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström 0x00, 0x4a, // message len 1610c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström 0x02, // SERVER_HELLO 1620c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström 0x00, 0x00, 0x46, // handshake len 1630c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström 0x03, 0x01, // SSL 3.1 1640c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström 0x42, 0x85, 0x45, 0xa7, 0x27, 0xa9, 0x5d, 0xa0, // server random 1650c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström 0xb3, 0xc5, 0xe7, 0x53, 0xda, 0x48, 0x2b, 0x3f, // 1660c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström 0xc6, 0x5a, 0xca, 0x89, 0xc1, 0x58, 0x52, 0xa1, // 1670c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström 0x78, 0x3c, 0x5b, 0x17, 0x46, 0x00, 0x85, 0x3f, // 1680c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström 0x20, // session id len 1690c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström 0x0e, 0xd3, 0x06, 0x72, 0x5b, 0x5b, 0x1b, 0x5f, // session id 1700c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström 0x15, 0xac, 0x13, 0xf9, 0x88, 0x53, 0x9d, 0x9b, // 1710c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström 0xe8, 0x3d, 0x7b, 0x0c, 0x30, 0x32, 0x6e, 0x38, // 1720c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström 0x4d, 0xa2, 0x75, 0x57, 0x41, 0x6c, 0x34, 0x5c, // 1730c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström 0x00, 0x04, // RSA/RC4-128/MD5 1740c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström 0x00 // null compression 175f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}; 176f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 177f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgAsyncSSLSocket::AsyncSSLSocket(AsyncSocket* socket) 178f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org : BufferedReadAdapter(socket, 1024) { 179f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 180f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 181f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgint AsyncSSLSocket::Connect(const SocketAddress& addr) { 182f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Begin buffering before we connect, so that there isn't a race condition 183f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // between potential senders and receiving the OnConnectEvent signal 184f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org BufferInput(true); 185f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return BufferedReadAdapter::Connect(addr); 186f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 187f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 188f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid AsyncSSLSocket::OnConnectEvent(AsyncSocket * socket) { 189f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org ASSERT(socket == socket_); 190f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // TODO: we could buffer output too... 191f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org VERIFY(sizeof(kSslClientHello) == 192f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org DirectSend(kSslClientHello, sizeof(kSslClientHello))); 193f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 194f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 195f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid AsyncSSLSocket::ProcessInput(char* data, size_t* len) { 196f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (*len < sizeof(kSslServerHello)) 197f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return; 198f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 199f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (memcmp(kSslServerHello, data, sizeof(kSslServerHello)) != 0) { 200f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org Close(); 201f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org SignalCloseEvent(this, 0); // TODO: error code? 202f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return; 203f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 204f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 205f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org *len -= sizeof(kSslServerHello); 206f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (*len > 0) { 207f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org memmove(data, data + sizeof(kSslServerHello), *len); 208f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 209f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 210f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org bool remainder = (*len > 0); 211f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org BufferInput(false); 212f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org SignalConnectEvent(this); 213f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 214f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // FIX: if SignalConnect causes the socket to be destroyed, we are in trouble 215f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (remainder) 216f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org SignalReadEvent(this); 217f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 218f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 219f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgAsyncSSLServerSocket::AsyncSSLServerSocket(AsyncSocket* socket) 220f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org : BufferedReadAdapter(socket, 1024) { 221f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org BufferInput(true); 222f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 223f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 224f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid AsyncSSLServerSocket::ProcessInput(char* data, size_t* len) { 225f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // We only accept client hello messages. 226f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (*len < sizeof(kSslClientHello)) { 227f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return; 228f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 229f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 230f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (memcmp(kSslClientHello, data, sizeof(kSslClientHello)) != 0) { 231f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org Close(); 232f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org SignalCloseEvent(this, 0); 233f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return; 234f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 235f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 236f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org *len -= sizeof(kSslClientHello); 237f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 238f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Clients should not send more data until the handshake is completed. 239f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org ASSERT(*len == 0); 240f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 241f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Send a server hello back to the client. 242f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org DirectSend(kSslServerHello, sizeof(kSslServerHello)); 243f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 244f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Handshake completed for us, redirect input to our parent. 245f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org BufferInput(false); 246f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 247f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 248f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org/////////////////////////////////////////////////////////////////////////////// 249f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 250f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgAsyncHttpsProxySocket::AsyncHttpsProxySocket(AsyncSocket* socket, 251f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org const std::string& user_agent, 252f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org const SocketAddress& proxy, 253f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org const std::string& username, 254f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org const CryptString& password) 255f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org : BufferedReadAdapter(socket, 1024), proxy_(proxy), agent_(user_agent), 256f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org user_(username), pass_(password), force_connect_(false), state_(PS_ERROR), 257f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org context_(0) { 258f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 259f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 260f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgAsyncHttpsProxySocket::~AsyncHttpsProxySocket() { 261f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org delete context_; 262f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 263f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 264f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgint AsyncHttpsProxySocket::Connect(const SocketAddress& addr) { 265f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org int ret; 266f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org LOG(LS_VERBOSE) << "AsyncHttpsProxySocket::Connect(" 267f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org << proxy_.ToSensitiveString() << ")"; 268f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org dest_ = addr; 269f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org state_ = PS_INIT; 270f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (ShouldIssueConnect()) { 271f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org BufferInput(true); 272f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 273f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org ret = BufferedReadAdapter::Connect(proxy_); 274f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // TODO: Set state_ appropriately if Connect fails. 275f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return ret; 276f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 277f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 278f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgSocketAddress AsyncHttpsProxySocket::GetRemoteAddress() const { 279f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return dest_; 280f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 281f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 282f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgint AsyncHttpsProxySocket::Close() { 283f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org headers_.clear(); 284f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org state_ = PS_ERROR; 285f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org dest_.Clear(); 286f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org delete context_; 287f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org context_ = NULL; 288f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return BufferedReadAdapter::Close(); 289f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 290f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 291f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgSocket::ConnState AsyncHttpsProxySocket::GetState() const { 292f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (state_ < PS_TUNNEL) { 293f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return CS_CONNECTING; 294f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else if (state_ == PS_TUNNEL) { 295f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return CS_CONNECTED; 296f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else { 297f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return CS_CLOSED; 298f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 299f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 300f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 301f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid AsyncHttpsProxySocket::OnConnectEvent(AsyncSocket * socket) { 302f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org LOG(LS_VERBOSE) << "AsyncHttpsProxySocket::OnConnectEvent"; 303f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (!ShouldIssueConnect()) { 304f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org state_ = PS_TUNNEL; 305f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org BufferedReadAdapter::OnConnectEvent(socket); 306f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return; 307f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 308f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org SendRequest(); 309f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 310f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 311f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid AsyncHttpsProxySocket::OnCloseEvent(AsyncSocket * socket, int err) { 312f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org LOG(LS_VERBOSE) << "AsyncHttpsProxySocket::OnCloseEvent(" << err << ")"; 313f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if ((state_ == PS_WAIT_CLOSE) && (err == 0)) { 314f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org state_ = PS_ERROR; 315f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org Connect(dest_); 316f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else { 317f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org BufferedReadAdapter::OnCloseEvent(socket, err); 318f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 319f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 320f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 321f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid AsyncHttpsProxySocket::ProcessInput(char* data, size_t* len) { 322f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org size_t start = 0; 323f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org for (size_t pos = start; state_ < PS_TUNNEL && pos < *len;) { 324f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (state_ == PS_SKIP_BODY) { 325ff689be3c0c59c1be29aaa0697aa0f762566d6c6andresp@webrtc.org size_t consume = std::min(*len - pos, content_length_); 326f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org pos += consume; 327f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org start = pos; 328f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org content_length_ -= consume; 329f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (content_length_ == 0) { 330f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org EndResponse(); 331f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 332f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org continue; 333f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 334f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 335f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (data[pos++] != '\n') 336f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org continue; 337f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 338f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org size_t len = pos - start - 1; 339f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if ((len > 0) && (data[start + len - 1] == '\r')) 340f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org --len; 341f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 342f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org data[start + len] = 0; 343f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org ProcessLine(data + start, len); 344f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org start = pos; 345f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 346f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 347f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org *len -= start; 348f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (*len > 0) { 349f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org memmove(data, data + start, *len); 350f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 351f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 352f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (state_ != PS_TUNNEL) 353f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return; 354f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 355f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org bool remainder = (*len > 0); 356f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org BufferInput(false); 357f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org SignalConnectEvent(this); 358f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 359f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // FIX: if SignalConnect causes the socket to be destroyed, we are in trouble 360f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (remainder) 361f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org SignalReadEvent(this); // TODO: signal this?? 362f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 363f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 364f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgbool AsyncHttpsProxySocket::ShouldIssueConnect() const { 365f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // TODO: Think about whether a more sophisticated test 366f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // than dest port == 80 is needed. 367f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return force_connect_ || (dest_.port() != 80); 368f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 369f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 370f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid AsyncHttpsProxySocket::SendRequest() { 371f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org std::stringstream ss; 372f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org ss << "CONNECT " << dest_.ToString() << " HTTP/1.0\r\n"; 373f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org ss << "User-Agent: " << agent_ << "\r\n"; 374f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org ss << "Host: " << dest_.HostAsURIString() << "\r\n"; 375f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org ss << "Content-Length: 0\r\n"; 376f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org ss << "Proxy-Connection: Keep-Alive\r\n"; 377f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org ss << headers_; 378f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org ss << "\r\n"; 379f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org std::string str = ss.str(); 380f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org DirectSend(str.c_str(), str.size()); 381f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org state_ = PS_LEADER; 382f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org expect_close_ = true; 383f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org content_length_ = 0; 384f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org headers_.clear(); 385f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 386f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org LOG(LS_VERBOSE) << "AsyncHttpsProxySocket >> " << str; 387f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 388f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 389f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid AsyncHttpsProxySocket::ProcessLine(char * data, size_t len) { 390f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org LOG(LS_VERBOSE) << "AsyncHttpsProxySocket << " << data; 391f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 392f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (len == 0) { 393f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (state_ == PS_TUNNEL_HEADERS) { 394f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org state_ = PS_TUNNEL; 395f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else if (state_ == PS_ERROR_HEADERS) { 396f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org Error(defer_error_); 397f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return; 398f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else if (state_ == PS_SKIP_HEADERS) { 399f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (content_length_) { 400f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org state_ = PS_SKIP_BODY; 401f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else { 402f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org EndResponse(); 403f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return; 404f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 405f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else { 406f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org static bool report = false; 407f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (!unknown_mechanisms_.empty() && !report) { 408f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org report = true; 409f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org std::string msg( 410f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org "Unable to connect to the Google Talk service due to an incompatibility " 411f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org "with your proxy.\r\nPlease help us resolve this issue by submitting the " 412f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org "following information to us using our technical issue submission form " 413f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org "at:\r\n\r\n" 414f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org "http://www.google.com/support/talk/bin/request.py\r\n\r\n" 415f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org "We apologize for the inconvenience.\r\n\r\n" 416f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org "Information to submit to Google: " 417f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org ); 418f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org //std::string msg("Please report the following information to foo@bar.com:\r\nUnknown methods: "); 419f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org msg.append(unknown_mechanisms_); 420f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#if defined(WEBRTC_WIN) 421f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org MessageBoxA(0, msg.c_str(), "Oops!", MB_OK); 422f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#endif 423f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#if defined(WEBRTC_POSIX) 424f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // TODO: Raise a signal so the UI can be separated. 425f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org LOG(LS_ERROR) << "Oops!\n\n" << msg; 426f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#endif 427f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 428f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Unexpected end of headers 429f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org Error(0); 430f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return; 431f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 432f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else if (state_ == PS_LEADER) { 433f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org unsigned int code; 434f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (sscanf(data, "HTTP/%*u.%*u %u", &code) != 1) { 435f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org Error(0); 436f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return; 437f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 438f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org switch (code) { 439f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org case 200: 440f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // connection good! 441f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org state_ = PS_TUNNEL_HEADERS; 442f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return; 443f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#if defined(HTTP_STATUS_PROXY_AUTH_REQ) && (HTTP_STATUS_PROXY_AUTH_REQ != 407) 444f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#error Wrong code for HTTP_STATUS_PROXY_AUTH_REQ 445f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#endif 446f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org case 407: // HTTP_STATUS_PROXY_AUTH_REQ 447f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org state_ = PS_AUTHENTICATE; 448f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return; 449f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org default: 450f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org defer_error_ = 0; 451f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org state_ = PS_ERROR_HEADERS; 452f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return; 453f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 454f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else if ((state_ == PS_AUTHENTICATE) 455f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org && (_strnicmp(data, "Proxy-Authenticate:", 19) == 0)) { 456f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org std::string response, auth_method; 457f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org switch (HttpAuthenticate(data + 19, len - 19, 458f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org proxy_, "CONNECT", "/", 459f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org user_, pass_, context_, response, auth_method)) { 460f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org case HAR_IGNORE: 461f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org LOG(LS_VERBOSE) << "Ignoring Proxy-Authenticate: " << auth_method; 462f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (!unknown_mechanisms_.empty()) 463f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org unknown_mechanisms_.append(", "); 464f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org unknown_mechanisms_.append(auth_method); 465f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org break; 466f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org case HAR_RESPONSE: 467f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org headers_ = "Proxy-Authorization: "; 468f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org headers_.append(response); 469f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org headers_.append("\r\n"); 470f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org state_ = PS_SKIP_HEADERS; 471f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org unknown_mechanisms_.clear(); 472f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org break; 473f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org case HAR_CREDENTIALS: 474f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org defer_error_ = SOCKET_EACCES; 475f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org state_ = PS_ERROR_HEADERS; 476f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org unknown_mechanisms_.clear(); 477f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org break; 478f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org case HAR_ERROR: 479f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org defer_error_ = 0; 480f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org state_ = PS_ERROR_HEADERS; 481f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org unknown_mechanisms_.clear(); 482f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org break; 483f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 484f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else if (_strnicmp(data, "Content-Length:", 15) == 0) { 485f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org content_length_ = strtoul(data + 15, 0, 0); 486f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else if (_strnicmp(data, "Proxy-Connection: Keep-Alive", 28) == 0) { 487f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org expect_close_ = false; 488f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org /* 489f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else if (_strnicmp(data, "Connection: close", 17) == 0) { 490f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org expect_close_ = true; 491f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org */ 492f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 493f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 494f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 495f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid AsyncHttpsProxySocket::EndResponse() { 496f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (!expect_close_) { 497f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org SendRequest(); 498f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return; 499f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 500f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 501f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // No point in waiting for the server to close... let's close now 502f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // TODO: Refactor out PS_WAIT_CLOSE 503f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org state_ = PS_WAIT_CLOSE; 504f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org BufferedReadAdapter::Close(); 505f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org OnCloseEvent(this, 0); 506f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 507f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 508f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid AsyncHttpsProxySocket::Error(int error) { 509f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org BufferInput(false); 510f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org Close(); 511f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org SetError(error); 512f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org SignalCloseEvent(this, error); 513f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 514f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 515f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org/////////////////////////////////////////////////////////////////////////////// 516f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 517f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgAsyncSocksProxySocket::AsyncSocksProxySocket(AsyncSocket* socket, 518f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org const SocketAddress& proxy, 519f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org const std::string& username, 520f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org const CryptString& password) 521f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org : BufferedReadAdapter(socket, 1024), state_(SS_ERROR), proxy_(proxy), 522f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org user_(username), pass_(password) { 523f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 524f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 52567186fe00cc68cbe03aa66d17fb4962458ca96d2kwiberg@webrtc.orgAsyncSocksProxySocket::~AsyncSocksProxySocket() = default; 52667186fe00cc68cbe03aa66d17fb4962458ca96d2kwiberg@webrtc.org 527f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgint AsyncSocksProxySocket::Connect(const SocketAddress& addr) { 528f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org int ret; 529f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org dest_ = addr; 530f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org state_ = SS_INIT; 531f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org BufferInput(true); 532f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org ret = BufferedReadAdapter::Connect(proxy_); 533f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // TODO: Set state_ appropriately if Connect fails. 534f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return ret; 535f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 536f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 537f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgSocketAddress AsyncSocksProxySocket::GetRemoteAddress() const { 538f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return dest_; 539f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 540f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 541f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgint AsyncSocksProxySocket::Close() { 542f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org state_ = SS_ERROR; 543f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org dest_.Clear(); 544f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return BufferedReadAdapter::Close(); 545f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 546f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 547f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgSocket::ConnState AsyncSocksProxySocket::GetState() const { 548f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (state_ < SS_TUNNEL) { 549f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return CS_CONNECTING; 550f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else if (state_ == SS_TUNNEL) { 551f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return CS_CONNECTED; 552f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else { 553f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return CS_CLOSED; 554f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 555f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 556f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 557f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid AsyncSocksProxySocket::OnConnectEvent(AsyncSocket* socket) { 558f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org SendHello(); 559f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 560f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 561f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid AsyncSocksProxySocket::ProcessInput(char* data, size_t* len) { 562f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org ASSERT(state_ < SS_TUNNEL); 563f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 564f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org ByteBuffer response(data, *len); 565f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 566f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (state_ == SS_HELLO) { 5670c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström uint8_t ver, method; 568f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (!response.ReadUInt8(&ver) || 569f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org !response.ReadUInt8(&method)) 570f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return; 571f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 572f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (ver != 5) { 573f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org Error(0); 574f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return; 575f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 576f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 577f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (method == 0) { 578f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org SendConnect(); 579f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else if (method == 2) { 580f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org SendAuth(); 581f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else { 582f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org Error(0); 583f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return; 584f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 585f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else if (state_ == SS_AUTH) { 5860c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström uint8_t ver, status; 587f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (!response.ReadUInt8(&ver) || 588f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org !response.ReadUInt8(&status)) 589f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return; 590f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 591f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if ((ver != 1) || (status != 0)) { 592f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org Error(SOCKET_EACCES); 593f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return; 594f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 595f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 596f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org SendConnect(); 597f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else if (state_ == SS_CONNECT) { 5980c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström uint8_t ver, rep, rsv, atyp; 599f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (!response.ReadUInt8(&ver) || 600f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org !response.ReadUInt8(&rep) || 601f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org !response.ReadUInt8(&rsv) || 602f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org !response.ReadUInt8(&atyp)) 603f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return; 604f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 605f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if ((ver != 5) || (rep != 0)) { 606f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org Error(0); 607f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return; 608f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 609f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 6100c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström uint16_t port; 611f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (atyp == 1) { 6120c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström uint32_t addr; 613f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (!response.ReadUInt32(&addr) || 614f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org !response.ReadUInt16(&port)) 615f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return; 616f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org LOG(LS_VERBOSE) << "Bound on " << addr << ":" << port; 617f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else if (atyp == 3) { 6180c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström uint8_t len; 619f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org std::string addr; 620f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (!response.ReadUInt8(&len) || 621f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org !response.ReadString(&addr, len) || 622f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org !response.ReadUInt16(&port)) 623f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return; 624f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org LOG(LS_VERBOSE) << "Bound on " << addr << ":" << port; 625f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else if (atyp == 4) { 626f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org std::string addr; 627f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (!response.ReadString(&addr, 16) || 628f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org !response.ReadUInt16(&port)) 629f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return; 630f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org LOG(LS_VERBOSE) << "Bound on <IPV6>:" << port; 631f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else { 632f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org Error(0); 633f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return; 634f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 635f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 636f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org state_ = SS_TUNNEL; 637f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 638f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 639f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Consume parsed data 640f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org *len = response.Length(); 641f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org memcpy(data, response.Data(), *len); 642f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 643f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (state_ != SS_TUNNEL) 644f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return; 645f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 646f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org bool remainder = (*len > 0); 647f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org BufferInput(false); 648f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org SignalConnectEvent(this); 649f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 650f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // FIX: if SignalConnect causes the socket to be destroyed, we are in trouble 651f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (remainder) 652f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org SignalReadEvent(this); // TODO: signal this?? 653f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 654f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 655f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid AsyncSocksProxySocket::SendHello() { 656f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org ByteBuffer request; 657f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org request.WriteUInt8(5); // Socks Version 658f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (user_.empty()) { 659f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org request.WriteUInt8(1); // Authentication Mechanisms 660f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org request.WriteUInt8(0); // No authentication 661f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else { 662f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org request.WriteUInt8(2); // Authentication Mechanisms 663f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org request.WriteUInt8(0); // No authentication 664f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org request.WriteUInt8(2); // Username/Password 665f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 666f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org DirectSend(request.Data(), request.Length()); 667f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org state_ = SS_HELLO; 668f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 669f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 670f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid AsyncSocksProxySocket::SendAuth() { 671f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org ByteBuffer request; 672f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org request.WriteUInt8(1); // Negotiation Version 6730c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström request.WriteUInt8(static_cast<uint8_t>(user_.size())); 674f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org request.WriteString(user_); // Username 6750c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström request.WriteUInt8(static_cast<uint8_t>(pass_.GetLength())); 676f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org size_t len = pass_.GetLength() + 1; 677f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org char * sensitive = new char[len]; 678f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org pass_.CopyTo(sensitive, true); 679f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org request.WriteString(sensitive); // Password 680f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org memset(sensitive, 0, len); 681f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org delete [] sensitive; 682f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org DirectSend(request.Data(), request.Length()); 683f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org state_ = SS_AUTH; 684f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 685f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 686f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid AsyncSocksProxySocket::SendConnect() { 687f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org ByteBuffer request; 688f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org request.WriteUInt8(5); // Socks Version 689f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org request.WriteUInt8(1); // CONNECT 690f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org request.WriteUInt8(0); // Reserved 69120a34619080005c3b0e49d85b307113ea2b180c3tfarina if (dest_.IsUnresolvedIP()) { 692f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org std::string hostname = dest_.hostname(); 693f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org request.WriteUInt8(3); // DOMAINNAME 6940c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström request.WriteUInt8(static_cast<uint8_t>(hostname.size())); 695f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org request.WriteString(hostname); // Destination Hostname 696f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else { 697f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org request.WriteUInt8(1); // IPV4 698f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org request.WriteUInt32(dest_.ip()); // Destination IP 699f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 700f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org request.WriteUInt16(dest_.port()); // Destination Port 701f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org DirectSend(request.Data(), request.Length()); 702f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org state_ = SS_CONNECT; 703f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 704f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 705f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid AsyncSocksProxySocket::Error(int error) { 706f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org state_ = SS_ERROR; 707f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org BufferInput(false); 708f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org Close(); 709f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org SetError(SOCKET_EACCES); 710f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org SignalCloseEvent(this, error); 711f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 712f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 713f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgAsyncSocksProxyServerSocket::AsyncSocksProxyServerSocket(AsyncSocket* socket) 714f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org : AsyncProxyServerSocket(socket, kBufferSize), state_(SS_HELLO) { 715f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org BufferInput(true); 716f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 717f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 718f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid AsyncSocksProxyServerSocket::ProcessInput(char* data, size_t* len) { 719f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // TODO: See if the whole message has arrived 720f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org ASSERT(state_ < SS_CONNECT_PENDING); 721f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 722f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org ByteBuffer response(data, *len); 723f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (state_ == SS_HELLO) { 724f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org HandleHello(&response); 725f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else if (state_ == SS_AUTH) { 726f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org HandleAuth(&response); 727f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else if (state_ == SS_CONNECT) { 728f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org HandleConnect(&response); 729f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 730f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 731f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Consume parsed data 732f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org *len = response.Length(); 733f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org memcpy(data, response.Data(), *len); 734f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 735f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 736f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid AsyncSocksProxyServerSocket::DirectSend(const ByteBuffer& buf) { 737f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org BufferedReadAdapter::DirectSend(buf.Data(), buf.Length()); 738f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 739f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 740f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid AsyncSocksProxyServerSocket::HandleHello(ByteBuffer* request) { 7410c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström uint8_t ver, num_methods; 742f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (!request->ReadUInt8(&ver) || 743f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org !request->ReadUInt8(&num_methods)) { 744f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org Error(0); 745f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return; 746f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 747f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 748f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (ver != 5) { 749f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org Error(0); 750f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return; 751f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 752f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 753f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Handle either no-auth (0) or user/pass auth (2) 7540c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström uint8_t method = 0xFF; 755f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (num_methods > 0 && !request->ReadUInt8(&method)) { 756f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org Error(0); 757f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return; 758f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 759f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 760f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // TODO: Ask the server which method to use. 761f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org SendHelloReply(method); 762f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (method == 0) { 763f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org state_ = SS_CONNECT; 764f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else if (method == 2) { 765f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org state_ = SS_AUTH; 766f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else { 767f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org state_ = SS_ERROR; 768f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 769f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 770f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 7710c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boströmvoid AsyncSocksProxyServerSocket::SendHelloReply(uint8_t method) { 772f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org ByteBuffer response; 773f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org response.WriteUInt8(5); // Socks Version 774f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org response.WriteUInt8(method); // Auth method 775f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org DirectSend(response); 776f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 777f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 778f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid AsyncSocksProxyServerSocket::HandleAuth(ByteBuffer* request) { 7790c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström uint8_t ver, user_len, pass_len; 780f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org std::string user, pass; 781f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (!request->ReadUInt8(&ver) || 782f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org !request->ReadUInt8(&user_len) || 783f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org !request->ReadString(&user, user_len) || 784f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org !request->ReadUInt8(&pass_len) || 785f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org !request->ReadString(&pass, pass_len)) { 786f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org Error(0); 787f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return; 788f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 789f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 790f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // TODO: Allow for checking of credentials. 791f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org SendAuthReply(0); 792f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org state_ = SS_CONNECT; 793f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 794f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 7950c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boströmvoid AsyncSocksProxyServerSocket::SendAuthReply(uint8_t result) { 796f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org ByteBuffer response; 797f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org response.WriteUInt8(1); // Negotiation Version 798f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org response.WriteUInt8(result); 799f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org DirectSend(response); 800f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 801f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 802f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid AsyncSocksProxyServerSocket::HandleConnect(ByteBuffer* request) { 8030c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström uint8_t ver, command, reserved, addr_type; 8040c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström uint32_t ip; 8050c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström uint16_t port; 806f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (!request->ReadUInt8(&ver) || 807f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org !request->ReadUInt8(&command) || 808f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org !request->ReadUInt8(&reserved) || 809f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org !request->ReadUInt8(&addr_type) || 810f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org !request->ReadUInt32(&ip) || 811f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org !request->ReadUInt16(&port)) { 812f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org Error(0); 813f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return; 814f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 815f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 816f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (ver != 5 || command != 1 || 817f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org reserved != 0 || addr_type != 1) { 818f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org Error(0); 819f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return; 820f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 821f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 822f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org SignalConnectRequest(this, SocketAddress(ip, port)); 823f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org state_ = SS_CONNECT_PENDING; 824f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 825f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 826f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid AsyncSocksProxyServerSocket::SendConnectResult(int result, 827f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org const SocketAddress& addr) { 828f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (state_ != SS_CONNECT_PENDING) 829f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return; 830f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 831f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org ByteBuffer response; 832f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org response.WriteUInt8(5); // Socks version 833f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org response.WriteUInt8((result != 0)); // 0x01 is generic error 834f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org response.WriteUInt8(0); // reserved 835f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org response.WriteUInt8(1); // IPv4 address 836f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org response.WriteUInt32(addr.ip()); 837f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org response.WriteUInt16(addr.port()); 838f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org DirectSend(response); 839f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org BufferInput(false); 840f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org state_ = SS_TUNNEL; 841f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 842f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 843f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid AsyncSocksProxyServerSocket::Error(int error) { 844f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org state_ = SS_ERROR; 845f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org BufferInput(false); 846f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org Close(); 847f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org SetError(SOCKET_EACCES); 848f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org SignalCloseEvent(this, error); 849f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 850f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 851f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org/////////////////////////////////////////////////////////////////////////////// 852f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 853f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgLoggingSocketAdapter::LoggingSocketAdapter(AsyncSocket* socket, 854f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org LoggingSeverity level, 855f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org const char * label, bool hex_mode) 856f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org : AsyncSocketAdapter(socket), level_(level), hex_mode_(hex_mode) { 857f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org label_.append("["); 858f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org label_.append(label); 859f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org label_.append("]"); 860f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 861f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 862f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgint LoggingSocketAdapter::Send(const void *pv, size_t cb) { 863f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org int res = AsyncSocketAdapter::Send(pv, cb); 864f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (res > 0) 865f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org LogMultiline(level_, label_.c_str(), false, pv, res, hex_mode_, &lms_); 866f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return res; 867f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 868f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 869f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgint LoggingSocketAdapter::SendTo(const void *pv, size_t cb, 870f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org const SocketAddress& addr) { 871f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org int res = AsyncSocketAdapter::SendTo(pv, cb, addr); 872f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (res > 0) 873f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org LogMultiline(level_, label_.c_str(), false, pv, res, hex_mode_, &lms_); 874f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return res; 875f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 876f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 877f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgint LoggingSocketAdapter::Recv(void *pv, size_t cb) { 878f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org int res = AsyncSocketAdapter::Recv(pv, cb); 879f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (res > 0) 880f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org LogMultiline(level_, label_.c_str(), true, pv, res, hex_mode_, &lms_); 881f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return res; 882f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 883f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 884f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgint LoggingSocketAdapter::RecvFrom(void *pv, size_t cb, SocketAddress *paddr) { 885f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org int res = AsyncSocketAdapter::RecvFrom(pv, cb, paddr); 886f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (res > 0) 887f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org LogMultiline(level_, label_.c_str(), true, pv, res, hex_mode_, &lms_); 888f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return res; 889f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 890f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 891f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgint LoggingSocketAdapter::Close() { 892f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org LogMultiline(level_, label_.c_str(), false, NULL, 0, hex_mode_, &lms_); 893f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org LogMultiline(level_, label_.c_str(), true, NULL, 0, hex_mode_, &lms_); 894f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org LOG_V(level_) << label_ << " Closed locally"; 895f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return socket_->Close(); 896f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 897f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 898f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid LoggingSocketAdapter::OnConnectEvent(AsyncSocket * socket) { 899f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org LOG_V(level_) << label_ << " Connected"; 900f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org AsyncSocketAdapter::OnConnectEvent(socket); 901f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 902f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 903f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid LoggingSocketAdapter::OnCloseEvent(AsyncSocket * socket, int err) { 904f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org LogMultiline(level_, label_.c_str(), false, NULL, 0, hex_mode_, &lms_); 905f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org LogMultiline(level_, label_.c_str(), true, NULL, 0, hex_mode_, &lms_); 906f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org LOG_V(level_) << label_ << " Closed with error: " << err; 907f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org AsyncSocketAdapter::OnCloseEvent(socket, err); 908f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 909f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 910f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org/////////////////////////////////////////////////////////////////////////////// 911f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 912f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} // namespace rtc 913