PRStatus nsSOCKSSocketInfo::WriteV5AuthRequest() { NS_ABORT_IF_FALSE(mVersion == 5, "SOCKS version must be 5!"); mState = SOCKS5_WRITE_AUTH_REQUEST; // Send an initial SOCKS 5 greeting LOGDEBUG(("socks5: sending auth methods")); WriteUint8(0x05); // version -- 5 WriteUint8(0x01); // # auth methods -- 1 WriteUint8(0x00); // we don't support authentication return PR_SUCCESS; }
PRStatus nsSOCKSSocketInfo::WriteV4ConnectRequest() { PRNetAddr *addr = &mDestinationAddr; int32_t proxy_resolve; NS_ABORT_IF_FALSE(mState == SOCKS_CONNECTING_TO_PROXY, "Invalid state!"); proxy_resolve = mFlags & nsISocketProvider::PROXY_RESOLVES_HOST; mDataLength = 0; mState = SOCKS4_WRITE_CONNECT_REQUEST; LOGDEBUG(("socks4: sending connection request (socks4a resolve? %s)", proxy_resolve? "yes" : "no")); // Send a SOCKS 4 connect request. WriteUint8(0x04); // version -- 4 WriteUint8(0x01); // command -- connect WriteNetPort(addr); if (proxy_resolve) { // Add the full name, null-terminated, to the request // according to SOCKS 4a. A fake IP address, with the first // four bytes set to 0 and the last byte set to something other // than 0, is used to notify the proxy that this is a SOCKS 4a // request. This request type works for Tor and perhaps others. WriteUint32(PR_htonl(0x00000001)); // Fake IP WriteUint8(0x00); // Send an emtpy username if (mDestinationHost.Length() > MAX_HOSTNAME_LEN) { LOGERROR(("socks4: destination host name is too long!")); HandshakeFinished(PR_BAD_ADDRESS_ERROR); return PR_FAILURE; } WriteString(mDestinationHost); // Hostname WriteUint8(0x00); } else if (PR_NetAddrFamily(addr) == PR_AF_INET) { WriteNetAddr(addr); // Add the IPv4 address WriteUint8(0x00); // Send an emtpy username } else if (PR_NetAddrFamily(addr) == PR_AF_INET6) { LOGERROR(("socks: SOCKS 4 can't handle IPv6 addresses!")); HandshakeFinished(PR_BAD_ADDRESS_ERROR); return PR_FAILURE; } return PR_SUCCESS; }
PRStatus nsSOCKSSocketInfo::WriteV5ConnectRequest() { // Send SOCKS 5 connect request PRNetAddr *addr = &mDestinationAddr; int32_t proxy_resolve; proxy_resolve = mFlags & nsISocketProvider::PROXY_RESOLVES_HOST; LOGDEBUG(("socks5: sending connection request (socks5 resolve? %s)", proxy_resolve? "yes" : "no")); mDataLength = 0; mState = SOCKS5_WRITE_CONNECT_REQUEST; WriteUint8(0x05); // version -- 5 WriteUint8(0x01); // command -- connect WriteUint8(0x00); // reserved // Add the address to the SOCKS 5 request. SOCKS 5 supports several // address types, so we pick the one that works best for us. if (proxy_resolve) { // Add the host name. Only a single byte is used to store the length, // so we must prevent long names from being used. if (mDestinationHost.Length() > MAX_HOSTNAME_LEN) { LOGERROR(("socks5: destination host name is too long!")); HandshakeFinished(PR_BAD_ADDRESS_ERROR); return PR_FAILURE; } WriteUint8(0x03); // addr type -- domainname WriteUint8(mDestinationHost.Length()); // name length WriteString(mDestinationHost); } else if (PR_NetAddrFamily(addr) == PR_AF_INET) { WriteUint8(0x01); // addr type -- IPv4 WriteNetAddr(addr); } else if (PR_NetAddrFamily(addr) == PR_AF_INET6) { WriteUint8(0x04); // addr type -- IPv6 WriteNetAddr(addr); } else { LOGERROR(("socks5: destination address of unknown type!")); HandshakeFinished(PR_BAD_ADDRESS_ERROR); return PR_FAILURE; } WriteNetPort(addr); // port return PR_SUCCESS; }
/** * This method encodes and writes an `int8_t` value to current input frame. * * Before using this method `BeginFrame()` must be called to start and prepare a new input frame. Otherwise, this * method does nothing and returns error status `OT_ERROR_INVALID_STATE`. * * If no buffer space is available, this method will discard and clear the current input frame and return the * error status `OT_ERROR_NO_BUFS`. * * @param[in] aInt8 The value to add to input frame. * * @retval OT_ERROR_NONE Successfully added given value to the frame. * @retval OT_ERROR_NO_BUFS Insufficient buffer space available to add the value. * @retval OT_ERROR_INVALID_STATE `BeginFrame()` has not been called earlier to start the frame. * */ otError WriteInt8(int8_t aInt8) { return WriteUint8(static_cast<uint8_t>(aInt8)); }