📄 socketadapters.cc
字号:
Error(0); return; } } else if (state_ == PS_LEADER) { uint32 code; if (sscanf(data, "HTTP/%*lu.%*lu %lu", &code) != 1) { Error(0); return; } switch (code) { case 200: // connection good! state_ = PS_TUNNEL_HEADERS; return;#if defined(HTTP_STATUS_PROXY_AUTH_REQ) && (HTTP_STATUS_PROXY_AUTH_REQ != 407)#error Wrong code for HTTP_STATUS_PROXY_AUTH_REQ#endif case 407: // HTTP_STATUS_PROXY_AUTH_REQ state_ = PS_AUTHENTICATE; return; default: defer_error_ = 0; state_ = PS_ERROR_HEADERS; return; } } else if ((state_ == PS_AUTHENTICATE) && (_strnicmp(data, "Proxy-Authenticate:", 19) == 0)) { std::string response, auth_method; switch (HttpAuthenticate(data + 19, len - 19, proxy_, "CONNECT", "/", user_, pass_, context_, response, auth_method)) { case HAR_IGNORE: LOG(LS_VERBOSE) << "Ignoring Proxy-Authenticate: " << auth_method; if (!unknown_mechanisms_.empty()) unknown_mechanisms_.append(", "); unknown_mechanisms_.append(auth_method); break; case HAR_RESPONSE: headers_ = "Proxy-Authorization: "; headers_.append(response); headers_.append("\r\n"); state_ = PS_SKIP_HEADERS; unknown_mechanisms_.clear(); break; case HAR_CREDENTIALS: defer_error_ = SOCKET_EACCES; state_ = PS_ERROR_HEADERS; unknown_mechanisms_.clear(); break; case HAR_ERROR: defer_error_ = 0; state_ = PS_ERROR_HEADERS; unknown_mechanisms_.clear(); break; } } else if (_strnicmp(data, "Content-Length:", 15) == 0) { content_length_ = strtoul(data + 15, 0, 0); } else if (_strnicmp(data, "Proxy-Connection: Keep-Alive", 28) == 0) { expect_close_ = false; /* } else if (_strnicmp(data, "Connection: close", 17) == 0) { expect_close_ = true; */ }}void AsyncHttpsProxySocket::EndResponse() { if (!expect_close_) { SendRequest(); return; } // No point in waiting for the server to close... let's close now // TODO: Refactor out PS_WAIT_CLOSE state_ = PS_WAIT_CLOSE; BufferedReadAdapter::Close(); OnCloseEvent(this, 0);}void AsyncHttpsProxySocket::Error(int error) { BufferInput(false); Close(); SetError(error); SignalCloseEvent(this, error);}///////////////////////////////////////////////////////////////////////////////AsyncSocksProxySocket::AsyncSocksProxySocket(AsyncSocket* socket, const SocketAddress& proxy, const std::string& username, const CryptString& password) : BufferedReadAdapter(socket, 1024), proxy_(proxy), user_(username), pass_(password), state_(SS_ERROR) {}int AsyncSocksProxySocket::Connect(const SocketAddress& addr) { dest_ = addr; BufferInput(true); return BufferedReadAdapter::Connect(proxy_);}SocketAddress AsyncSocksProxySocket::GetRemoteAddress() const { return dest_;}void AsyncSocksProxySocket::OnConnectEvent(AsyncSocket * socket) { SendHello();}void AsyncSocksProxySocket::ProcessInput(char * data, size_t& len) { ASSERT(state_ < SS_TUNNEL); ByteBuffer response(data, len); if (state_ == SS_HELLO) { uint8 ver, method; if (!response.ReadUInt8(ver) || !response.ReadUInt8(method)) return; if (ver != 5) { Error(0); return; } if (method == 0) { SendConnect(); } else if (method == 2) { SendAuth(); } else { Error(0); return; } } else if (state_ == SS_AUTH) { uint8 ver, status; if (!response.ReadUInt8(ver) || !response.ReadUInt8(status)) return; if ((ver != 1) || (status != 0)) { Error(SOCKET_EACCES); return; } SendConnect(); } else if (state_ == SS_CONNECT) { uint8 ver, rep, rsv, atyp; if (!response.ReadUInt8(ver) || !response.ReadUInt8(rep) || !response.ReadUInt8(rsv) || !response.ReadUInt8(atyp)) return; if ((ver != 5) || (rep != 0)) { Error(0); return; } uint16 port; if (atyp == 1) { uint32 addr; if (!response.ReadUInt32(addr) || !response.ReadUInt16(port)) return; LOG(LS_VERBOSE) << "Bound on " << addr << ":" << port; } else if (atyp == 3) { uint8 len; std::string addr; if (!response.ReadUInt8(len) || !response.ReadString(addr, len) || !response.ReadUInt16(port)) return; LOG(LS_VERBOSE) << "Bound on " << addr << ":" << port; } else if (atyp == 4) { std::string addr; if (!response.ReadString(addr, 16) || !response.ReadUInt16(port)) return; LOG(LS_VERBOSE) << "Bound on <IPV6>:" << port; } else { Error(0); return; } state_ = SS_TUNNEL; } // Consume parsed data len = response.Length(); memcpy(data, response.Data(), len); if (state_ != SS_TUNNEL) return; bool remainder = (len > 0); BufferInput(false); SignalConnectEvent(this); // FIX: if SignalConnect causes the socket to be destroyed, we are in trouble if (remainder) SignalReadEvent(this); // TODO: signal this??}void AsyncSocksProxySocket::SendHello() { ByteBuffer request; request.WriteUInt8(5); // Socks Version if (user_.empty()) { request.WriteUInt8(1); // Authentication Mechanisms request.WriteUInt8(0); // No authentication } else { request.WriteUInt8(2); // Authentication Mechanisms request.WriteUInt8(0); // No authentication request.WriteUInt8(2); // Username/Password } DirectSend(request.Data(), request.Length()); state_ = SS_HELLO;}void AsyncSocksProxySocket::SendAuth() { ByteBuffer request; request.WriteUInt8(1); // Negotiation Version request.WriteUInt8(static_cast<uint8>(user_.size())); request.WriteString(user_); // Username request.WriteUInt8(static_cast<uint8>(pass_.GetLength())); size_t len = pass_.GetLength() + 1; char * sensitive = new char[len]; pass_.CopyTo(sensitive, true); request.WriteString(sensitive); // Password memset(sensitive, 0, len); delete [] sensitive; DirectSend(request.Data(), request.Length()); state_ = SS_AUTH;}void AsyncSocksProxySocket::SendConnect() { ByteBuffer request; request.WriteUInt8(5); // Socks Version request.WriteUInt8(1); // CONNECT request.WriteUInt8(0); // Reserved if (dest_.IsUnresolved()) { std::string hostname = dest_.IPAsString(); request.WriteUInt8(3); // DOMAINNAME request.WriteUInt8(static_cast<uint8>(hostname.size())); request.WriteString(hostname); // Destination Hostname } else { request.WriteUInt8(1); // IPV4 request.WriteUInt32(dest_.ip()); // Destination IP } request.WriteUInt16(dest_.port()); // Destination Port DirectSend(request.Data(), request.Length()); state_ = SS_CONNECT;}void AsyncSocksProxySocket::Error(int error) { state_ = SS_ERROR; BufferInput(false); Close(); SetError(SOCKET_EACCES); SignalCloseEvent(this, error);}///////////////////////////////////////////////////////////////////////////////LoggingSocketAdapter::LoggingSocketAdapter(AsyncSocket* socket, LoggingSeverity level, const char * label, bool hex_mode): AsyncSocketAdapter(socket), level_(level), hex_mode_(hex_mode){ label_.append("["); label_.append(label); label_.append("]");}intLoggingSocketAdapter::Send(const void *pv, size_t cb) { int res = AsyncSocketAdapter::Send(pv, cb); if (res > 0) LogMultiline(level_, label_.c_str(), false, static_cast<const char *>(pv), res, hex_mode_, &lms_); return res;}intLoggingSocketAdapter::SendTo(const void *pv, size_t cb, const SocketAddress& addr) { int res = AsyncSocketAdapter::SendTo(pv, cb, addr); if (res > 0) LogMultiline(level_, label_.c_str(), false, static_cast<const char *>(pv), res, hex_mode_, &lms_); return res;}intLoggingSocketAdapter::Recv(void *pv, size_t cb) { int res = AsyncSocketAdapter::Recv(pv, cb); if (res > 0) LogMultiline(level_, label_.c_str(), true, static_cast<const char *>(pv), res, hex_mode_, &lms_); return res;}intLoggingSocketAdapter::RecvFrom(void *pv, size_t cb, SocketAddress *paddr) { int res = AsyncSocketAdapter::RecvFrom(pv, cb, paddr); if (res > 0) LogMultiline(level_, label_.c_str(), true, static_cast<const char *>(pv), res, hex_mode_, &lms_); return res;}voidLoggingSocketAdapter::OnConnectEvent(AsyncSocket * socket) { LOG_V(level_) << label_ << " Connected"; AsyncSocketAdapter::OnConnectEvent(socket);}voidLoggingSocketAdapter::OnCloseEvent(AsyncSocket * socket, int err) { LOG_V(level_) << label_ << " Closed with error: " << err; AsyncSocketAdapter::OnCloseEvent(socket, err);}///////////////////////////////////////////////////////////////////////////////} // namespace talk_base
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -