NetworkSocket.cpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682
  1. //
  2. // Created by Grishka on 29.03.17.
  3. //
  4. #include "NetworkSocket.h"
  5. #include <stdexcept>
  6. #include <algorithm>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #if defined(_WIN32)
  10. #include "os/windows/NetworkSocketWinsock.h"
  11. #include <winsock2.h>
  12. #else
  13. #include "os/posix/NetworkSocketPosix.h"
  14. #endif
  15. #include "logging.h"
  16. #include "VoIPServerConfig.h"
  17. #include "VoIPController.h"
  18. #include "Buffers.h"
  19. #define MIN_UDP_PORT 16384
  20. #define MAX_UDP_PORT 32768
  21. using namespace tgvoip;
  22. NetworkSocket::NetworkSocket(NetworkProtocol protocol) : protocol(protocol){
  23. ipv6Timeout=ServerConfig::GetSharedInstance()->GetDouble("nat64_fallback_timeout", 3);
  24. failed=false;
  25. }
  26. NetworkSocket::~NetworkSocket(){
  27. }
  28. std::string NetworkSocket::GetLocalInterfaceInfo(IPv4Address *inet4addr, IPv6Address *inet6addr){
  29. std::string r="not implemented";
  30. return r;
  31. }
  32. uint16_t NetworkSocket::GenerateLocalPort(){
  33. uint16_t rnd;
  34. VoIPController::crypto.rand_bytes(reinterpret_cast<uint8_t*>(&rnd), 2);
  35. return (uint16_t) ((rnd%(MAX_UDP_PORT-MIN_UDP_PORT))+MIN_UDP_PORT);
  36. }
  37. void NetworkSocket::SetMaxPriority(){
  38. }
  39. bool NetworkSocket::IsFailed(){
  40. return failed;
  41. }
  42. NetworkSocket *NetworkSocket::Create(NetworkProtocol protocol){
  43. #ifndef _WIN32
  44. return new NetworkSocketPosix(protocol);
  45. #else
  46. return new NetworkSocketWinsock(protocol);
  47. #endif
  48. }
  49. IPv4Address *NetworkSocket::ResolveDomainName(std::string name){
  50. #ifndef _WIN32
  51. return NetworkSocketPosix::ResolveDomainName(name);
  52. #else
  53. return NetworkSocketWinsock::ResolveDomainName(name);
  54. #endif
  55. }
  56. void NetworkSocket::GenerateTCPO2States(unsigned char* buffer, TCPO2State* recvState, TCPO2State* sendState){
  57. memset(recvState, 0, sizeof(TCPO2State));
  58. memset(sendState, 0, sizeof(TCPO2State));
  59. unsigned char nonce[64];
  60. uint32_t *first = reinterpret_cast<uint32_t*>(nonce), *second = first + 1;
  61. uint32_t first1 = 0x44414548U, first2 = 0x54534f50U, first3 = 0x20544547U, first4 = 0x20544547U, first5 = 0xeeeeeeeeU;
  62. uint32_t second1 = 0;
  63. do {
  64. VoIPController::crypto.rand_bytes(nonce, sizeof(nonce));
  65. } while (*first == first1 || *first == first2 || *first == first3 || *first == first4 || *first == first5 || *second == second1 || *reinterpret_cast<unsigned char*>(nonce) == 0xef);
  66. // prepare encryption key/iv
  67. memcpy(sendState->key, nonce + 8, 32);
  68. memcpy(sendState->iv, nonce + 8 + 32, 16);
  69. // prepare decryption key/iv
  70. char reversed[48];
  71. memcpy(reversed, nonce + 8, sizeof(reversed));
  72. std::reverse(reversed, reversed + sizeof(reversed));
  73. memcpy(recvState->key, reversed, 32);
  74. memcpy(recvState->iv, reversed + 32, 16);
  75. // write protocol identifier
  76. *reinterpret_cast<uint32_t*>(nonce + 56) = 0xefefefefU;
  77. memcpy(buffer, nonce, 56);
  78. EncryptForTCPO2(nonce, sizeof(nonce), sendState);
  79. memcpy(buffer+56, nonce+56, 8);
  80. }
  81. void NetworkSocket::EncryptForTCPO2(unsigned char *buffer, size_t len, TCPO2State *state){
  82. VoIPController::crypto.aes_ctr_encrypt(buffer, len, state->key, state->iv, state->ecount, &state->num);
  83. }
  84. size_t NetworkSocket::Receive(unsigned char *buffer, size_t len){
  85. NetworkPacket pkt={0};
  86. pkt.data=buffer;
  87. pkt.length=len;
  88. Receive(&pkt);
  89. return pkt.length;
  90. }
  91. size_t NetworkSocket::Send(unsigned char *buffer, size_t len){
  92. NetworkPacket pkt={0};
  93. pkt.data=buffer;
  94. pkt.length=len;
  95. Send(&pkt);
  96. return pkt.length;
  97. }
  98. bool NetworkAddress::operator==(const NetworkAddress &other) const{
  99. const IPv4Address* self4=dynamic_cast<const IPv4Address*>(this);
  100. const IPv4Address* other4=dynamic_cast<const IPv4Address*>((NetworkAddress*)&other);
  101. if(self4 && other4){
  102. return self4->GetAddress()==other4->GetAddress();
  103. }
  104. const IPv6Address* self6=dynamic_cast<const IPv6Address*>(this);
  105. const IPv6Address* other6=dynamic_cast<const IPv6Address*>((NetworkAddress*)&other);
  106. if(self6 && other6){
  107. return memcmp(self6->GetAddress(), other6->GetAddress(), 16)==0;
  108. }
  109. return false;
  110. }
  111. bool NetworkAddress::operator!=(const NetworkAddress &other) const{
  112. return !(*this == other);
  113. }
  114. IPv4Address::IPv4Address(std::string addr){
  115. #ifndef _WIN32
  116. this->address=NetworkSocketPosix::StringToV4Address(addr);
  117. #else
  118. this->address=NetworkSocketWinsock::StringToV4Address(addr);
  119. #endif
  120. }
  121. IPv4Address::IPv4Address(uint32_t addr){
  122. this->address=addr;
  123. }
  124. IPv4Address::IPv4Address(){
  125. this->address=0;
  126. }
  127. std::string IPv4Address::ToString() const{
  128. #ifndef _WIN32
  129. return NetworkSocketPosix::V4AddressToString(address);
  130. #else
  131. return NetworkSocketWinsock::V4AddressToString(address);
  132. #endif
  133. }
  134. bool IPv4Address::PrefixMatches(const unsigned int prefix, const NetworkAddress &other) const{
  135. const IPv4Address* v4=dynamic_cast<const IPv4Address*>(&other);
  136. if(v4){
  137. uint32_t mask=0xFFFFFFFF << (32-prefix);
  138. return (address & mask) == (v4->address & mask);
  139. }
  140. return false;
  141. }
  142. /*sockaddr &IPv4Address::ToSockAddr(uint16_t port){
  143. sockaddr_in sa;
  144. sa.sin_family=AF_INET;
  145. sa.sin_addr=addr;
  146. sa.sin_port=port;
  147. return *((sockaddr *) &sa);
  148. }*/
  149. uint32_t IPv4Address::GetAddress() const{
  150. return address;
  151. }
  152. bool IPv4Address::IsEmpty() const{
  153. return address==0;
  154. }
  155. IPv6Address::IPv6Address(std::string addr){
  156. #ifndef _WIN32
  157. NetworkSocketPosix::StringToV6Address(addr, this->address);
  158. #else
  159. NetworkSocketWinsock::StringToV6Address(addr, this->address);
  160. #endif
  161. }
  162. IPv6Address::IPv6Address(const uint8_t* addr){
  163. memcpy(address, addr, 16);
  164. }
  165. IPv6Address::IPv6Address(){
  166. memset(address, 0, 16);
  167. }
  168. std::string IPv6Address::ToString() const{
  169. #ifndef _WIN32
  170. return NetworkSocketPosix::V6AddressToString(address);
  171. #else
  172. return NetworkSocketWinsock::V6AddressToString(address);
  173. #endif
  174. }
  175. bool IPv6Address::PrefixMatches(const unsigned int prefix, const NetworkAddress &other) const{
  176. return false;
  177. }
  178. bool IPv6Address::IsEmpty() const{
  179. const uint64_t* a=reinterpret_cast<const uint64_t*>(address);
  180. return a[0]==0LL && a[1]==0LL;
  181. }
  182. /*sockaddr &IPv6Address::ToSockAddr(uint16_t port){
  183. sockaddr_in6 sa;
  184. sa.sin6_family=AF_INET6;
  185. sa.sin6_addr=addr;
  186. sa.sin6_port=port;
  187. return *((sockaddr *) &sa);
  188. }*/
  189. const uint8_t *IPv6Address::GetAddress() const{
  190. return address;
  191. }
  192. bool NetworkSocket::Select(std::vector<NetworkSocket *> &readFds, std::vector<NetworkSocket*> &writeFds, std::vector<NetworkSocket *> &errorFds, SocketSelectCanceller *canceller){
  193. #ifndef _WIN32
  194. return NetworkSocketPosix::Select(readFds, writeFds, errorFds, canceller);
  195. #else
  196. return NetworkSocketWinsock::Select(readFds, writeFds, errorFds, canceller);
  197. #endif
  198. }
  199. SocketSelectCanceller::~SocketSelectCanceller(){
  200. }
  201. SocketSelectCanceller *SocketSelectCanceller::Create(){
  202. #ifndef _WIN32
  203. return new SocketSelectCancellerPosix();
  204. #else
  205. return new SocketSelectCancellerWin32();
  206. #endif
  207. }
  208. NetworkSocketTCPObfuscated::NetworkSocketTCPObfuscated(NetworkSocket *wrapped) : NetworkSocketWrapper(PROTO_TCP){
  209. this->wrapped=wrapped;
  210. }
  211. NetworkSocketTCPObfuscated::~NetworkSocketTCPObfuscated(){
  212. if(wrapped)
  213. delete wrapped;
  214. }
  215. NetworkSocket *NetworkSocketTCPObfuscated::GetWrapped(){
  216. return wrapped;
  217. }
  218. void NetworkSocketTCPObfuscated::InitConnection(){
  219. unsigned char buf[64];
  220. GenerateTCPO2States(buf, &recvState, &sendState);
  221. wrapped->Send(buf, 64);
  222. }
  223. void NetworkSocketTCPObfuscated::Send(NetworkPacket *packet){
  224. BufferOutputStream os(packet->length+4);
  225. size_t len=packet->length/4;
  226. if(len<0x7F){
  227. os.WriteByte((unsigned char)len);
  228. }else{
  229. os.WriteByte(0x7F);
  230. os.WriteByte((unsigned char)(len & 0xFF));
  231. os.WriteByte((unsigned char)((len >> 8) & 0xFF));
  232. os.WriteByte((unsigned char)((len >> 16) & 0xFF));
  233. }
  234. os.WriteBytes(packet->data, packet->length);
  235. EncryptForTCPO2(os.GetBuffer(), os.GetLength(), &sendState);
  236. wrapped->Send(os.GetBuffer(), os.GetLength());
  237. //LOGD("Sent %u bytes", os.GetLength());
  238. }
  239. bool NetworkSocketTCPObfuscated::OnReadyToSend(){
  240. if(!initialized){
  241. //LOGV("Initializing TCPO2 connection");
  242. initialized=true;
  243. InitConnection();
  244. readyToSend=true;
  245. return false;
  246. }
  247. return wrapped->OnReadyToSend();
  248. }
  249. void NetworkSocketTCPObfuscated::Receive(NetworkPacket *packet){
  250. unsigned char len1;
  251. size_t packetLen=0;
  252. size_t offset=0;
  253. size_t len;
  254. len=wrapped->Receive(&len1, 1);
  255. if(len<=0){
  256. packet->length=0;
  257. return;
  258. }
  259. EncryptForTCPO2(&len1, 1, &recvState);
  260. if(len1<0x7F){
  261. packetLen=(size_t)len1*4;
  262. }else{
  263. unsigned char len2[3];
  264. len=wrapped->Receive(len2, 3);
  265. if(len<=0){
  266. packet->length=0;
  267. return;
  268. }
  269. EncryptForTCPO2(len2, 3, &recvState);
  270. packetLen=((size_t)len2[0] | ((size_t)len2[1] << 8) | ((size_t)len2[2] << 16))*4;
  271. }
  272. if(packetLen>packet->length){
  273. LOGW("packet too big to fit into buffer (%u vs %u)", (unsigned int)packetLen, (unsigned int)packet->length);
  274. packet->length=0;
  275. return;
  276. }
  277. while(offset<packetLen){
  278. len=wrapped->Receive(packet->data+offset, packetLen-offset);
  279. if(len<=0){
  280. packet->length=0;
  281. return;
  282. }
  283. offset+=len;
  284. }
  285. EncryptForTCPO2(packet->data, packetLen, &recvState);
  286. //packet->address=&itr->address;
  287. packet->length=packetLen;
  288. //packet->port=itr->port;
  289. packet->protocol=PROTO_TCP;
  290. packet->address=wrapped->GetConnectedAddress();
  291. packet->port=wrapped->GetConnectedPort();
  292. }
  293. void NetworkSocketTCPObfuscated::Open(){
  294. }
  295. void NetworkSocketTCPObfuscated::Close(){
  296. wrapped->Close();
  297. }
  298. void NetworkSocketTCPObfuscated::Connect(const NetworkAddress *address, uint16_t port){
  299. wrapped->Connect(address, port);
  300. }
  301. bool NetworkSocketTCPObfuscated::IsFailed(){
  302. return wrapped->IsFailed();
  303. }
  304. NetworkSocketSOCKS5Proxy::NetworkSocketSOCKS5Proxy(NetworkSocket *tcp, NetworkSocket *udp, std::string username, std::string password) : NetworkSocketWrapper(udp ? PROTO_UDP : PROTO_TCP){
  305. this->tcp=tcp;
  306. this->udp=udp;
  307. this->username=std::move(username);
  308. this->password=std::move(password);
  309. connectedAddress=NULL;
  310. }
  311. NetworkSocketSOCKS5Proxy::~NetworkSocketSOCKS5Proxy(){
  312. delete tcp;
  313. if(connectedAddress)
  314. delete connectedAddress;
  315. }
  316. void NetworkSocketSOCKS5Proxy::Send(NetworkPacket *packet){
  317. if(protocol==PROTO_TCP){
  318. tcp->Send(packet);
  319. }else if(protocol==PROTO_UDP){
  320. unsigned char buf[1500];
  321. BufferOutputStream out(buf, sizeof(buf));
  322. out.WriteInt16(0); // RSV
  323. out.WriteByte(0); // FRAG
  324. const IPv4Address* v4=dynamic_cast<IPv4Address*>(packet->address);
  325. const IPv6Address* v6=dynamic_cast<IPv6Address*>(packet->address);
  326. if(v4){
  327. out.WriteByte(1); // ATYP (IPv4)
  328. out.WriteInt32(v4->GetAddress());
  329. }else{
  330. out.WriteByte(4); // ATYP (IPv6)
  331. out.WriteBytes((unsigned char *) v6->GetAddress(), 16);
  332. }
  333. out.WriteInt16(htons(packet->port));
  334. out.WriteBytes(packet->data, packet->length);
  335. NetworkPacket p={0};
  336. p.data=buf;
  337. p.length=out.GetLength();
  338. p.address=connectedAddress;
  339. p.port=connectedPort;
  340. p.protocol=PROTO_UDP;
  341. udp->Send(&p);
  342. }
  343. }
  344. void NetworkSocketSOCKS5Proxy::Receive(NetworkPacket *packet){
  345. if(protocol==PROTO_TCP){
  346. tcp->Receive(packet);
  347. packet->address=connectedAddress;
  348. packet->port=connectedPort;
  349. }else if(protocol==PROTO_UDP){
  350. unsigned char buf[1500];
  351. NetworkPacket p={0};
  352. p.data=buf;
  353. p.length=sizeof(buf);
  354. udp->Receive(&p);
  355. if(p.length && p.address && *p.address==*connectedAddress && p.port==connectedPort){
  356. BufferInputStream in(buf, p.length);
  357. in.ReadInt16(); // RSV
  358. in.ReadByte(); // FRAG
  359. unsigned char atyp=in.ReadByte();
  360. if(atyp==1){ // IPv4
  361. lastRecvdV4=IPv4Address((uint32_t) in.ReadInt32());
  362. packet->address=&lastRecvdV4;
  363. }else if(atyp==4){ // IPv6
  364. unsigned char addr[16];
  365. in.ReadBytes(addr, 16);
  366. lastRecvdV6=IPv6Address(addr);
  367. packet->address=&lastRecvdV6;
  368. }
  369. packet->port=ntohs(in.ReadInt16());
  370. if(packet->length>=in.Remaining()){
  371. packet->length=in.Remaining();
  372. in.ReadBytes(packet->data, in.Remaining());
  373. }else{
  374. packet->length=0;
  375. LOGW("socks5: received packet too big");
  376. }
  377. }
  378. }
  379. }
  380. void NetworkSocketSOCKS5Proxy::Open(){
  381. }
  382. void NetworkSocketSOCKS5Proxy::Close(){
  383. tcp->Close();
  384. }
  385. void NetworkSocketSOCKS5Proxy::Connect(const NetworkAddress *address, uint16_t port){
  386. const IPv4Address* v4=dynamic_cast<const IPv4Address*>(address);
  387. const IPv6Address* v6=dynamic_cast<const IPv6Address*>(address);
  388. connectedAddress=v4 ? (NetworkAddress*)new IPv4Address(*v4) : (NetworkAddress*)new IPv6Address(*v6);
  389. connectedPort=port;
  390. }
  391. NetworkSocket *NetworkSocketSOCKS5Proxy::GetWrapped(){
  392. return protocol==PROTO_TCP ? tcp : udp;
  393. }
  394. void NetworkSocketSOCKS5Proxy::InitConnection(){
  395. }
  396. bool NetworkSocketSOCKS5Proxy::IsFailed(){
  397. return NetworkSocket::IsFailed() || tcp->IsFailed();
  398. }
  399. NetworkAddress *NetworkSocketSOCKS5Proxy::GetConnectedAddress(){
  400. return connectedAddress;
  401. }
  402. uint16_t NetworkSocketSOCKS5Proxy::GetConnectedPort(){
  403. return connectedPort;
  404. }
  405. bool NetworkSocketSOCKS5Proxy::OnReadyToSend(){
  406. //LOGV("on ready to send, state=%d", state);
  407. unsigned char buf[1024];
  408. if(state==ConnectionState::Initial){
  409. BufferOutputStream p(buf, sizeof(buf));
  410. p.WriteByte(5); // VER
  411. if(!username.empty()){
  412. p.WriteByte(2); // NMETHODS
  413. p.WriteByte(0); // no auth
  414. p.WriteByte(2); // user/pass
  415. }else{
  416. p.WriteByte(1); // NMETHODS
  417. p.WriteByte(0); // no auth
  418. }
  419. tcp->Send(buf, p.GetLength());
  420. state=ConnectionState::WaitingForAuthMethod;
  421. return false;
  422. }
  423. return udp ? udp->OnReadyToSend() : tcp->OnReadyToSend();
  424. }
  425. bool NetworkSocketSOCKS5Proxy::OnReadyToReceive(){
  426. //LOGV("on ready to receive state=%d", state);
  427. unsigned char buf[1024];
  428. if(state==ConnectionState::WaitingForAuthMethod){
  429. size_t l=tcp->Receive(buf, sizeof(buf));
  430. if(l<2 || tcp->IsFailed()){
  431. failed=true;
  432. return false;
  433. }
  434. BufferInputStream in(buf, l);
  435. unsigned char ver=in.ReadByte();
  436. unsigned char chosenMethod=in.ReadByte();
  437. LOGV("socks5: VER=%02X, METHOD=%02X", ver, chosenMethod);
  438. if(ver!=5){
  439. LOGW("socks5: incorrect VER in response");
  440. failed=true;
  441. return false;
  442. }
  443. if(chosenMethod==0){
  444. // connected, no further auth needed
  445. SendConnectionCommand();
  446. }else if(chosenMethod==2 && !username.empty()){
  447. BufferOutputStream p(buf, sizeof(buf));
  448. p.WriteByte(1); // VER
  449. p.WriteByte((unsigned char)(username.length()>255 ? 255 : username.length())); // ULEN
  450. p.WriteBytes((unsigned char*)username.c_str(), username.length()>255 ? 255 : username.length()); // UNAME
  451. p.WriteByte((unsigned char)(password.length()>255 ? 255 : password.length())); // PLEN
  452. p.WriteBytes((unsigned char*)password.c_str(), password.length()>255 ? 255 : password.length()); // PASSWD
  453. tcp->Send(buf, p.GetLength());
  454. state=ConnectionState::WaitingForAuthResult;
  455. }else{
  456. LOGW("socks5: unsupported auth method");
  457. failed=true;
  458. return false;
  459. }
  460. return false;
  461. }else if(state==ConnectionState::WaitingForAuthResult){
  462. size_t l=tcp->Receive(buf, sizeof(buf));
  463. if(l<2 || tcp->IsFailed()){
  464. failed=true;
  465. return false;
  466. }
  467. BufferInputStream in(buf, l);
  468. uint8_t ver=in.ReadByte();
  469. unsigned char status=in.ReadByte();
  470. LOGV("socks5: auth response VER=%02X, STATUS=%02X", ver, status);
  471. if(ver!=1){
  472. LOGW("socks5: auth response VER is incorrect");
  473. failed=true;
  474. return false;
  475. }
  476. if(status!=0){
  477. LOGW("socks5: username/password auth failed");
  478. failed=true;
  479. return false;
  480. }
  481. LOGV("socks5: authentication succeeded");
  482. SendConnectionCommand();
  483. return false;
  484. }else if(state==ConnectionState::WaitingForCommandResult){
  485. size_t l=tcp->Receive(buf, sizeof(buf));
  486. if(protocol==PROTO_TCP){
  487. if(l<2 || tcp->IsFailed()){
  488. LOGW("socks5: connect failed")
  489. failed=true;
  490. return false;
  491. }
  492. BufferInputStream in(buf, l);
  493. unsigned char ver=in.ReadByte();
  494. if(ver!=5){
  495. LOGW("socks5: connect: wrong ver in response");
  496. failed=true;
  497. return false;
  498. }
  499. unsigned char rep=in.ReadByte();
  500. if(rep!=0){
  501. LOGW("socks5: connect: failed with error %02X", rep);
  502. failed=true;
  503. return false;
  504. }
  505. LOGV("socks5: connect succeeded");
  506. state=ConnectionState::Connected;
  507. tcp=new NetworkSocketTCPObfuscated(tcp);
  508. readyToSend=true;
  509. return tcp->OnReadyToSend();
  510. }else if(protocol==PROTO_UDP){
  511. if(l<2 || tcp->IsFailed()){
  512. LOGW("socks5: udp associate failed");
  513. failed=true;
  514. return false;
  515. }
  516. try{
  517. BufferInputStream in(buf, l);
  518. unsigned char ver=in.ReadByte();
  519. unsigned char rep=in.ReadByte();
  520. if(ver!=5){
  521. LOGW("socks5: udp associate: wrong ver in response");
  522. failed=true;
  523. return false;
  524. }
  525. if(rep!=0){
  526. LOGW("socks5: udp associate failed with error %02X", rep);
  527. failed=true;
  528. return false;
  529. }
  530. in.ReadByte(); // RSV
  531. unsigned char atyp=in.ReadByte();
  532. if(atyp==1){
  533. uint32_t addr=(uint32_t) in.ReadInt32();
  534. connectedAddress=new IPv4Address(addr);
  535. }else if(atyp==3){
  536. unsigned char len=in.ReadByte();
  537. char domain[256];
  538. memset(domain, 0, sizeof(domain));
  539. in.ReadBytes((unsigned char*)domain, len);
  540. LOGD("address type is domain, address=%s", domain);
  541. connectedAddress=ResolveDomainName(std::string(domain));
  542. if(!connectedAddress){
  543. LOGW("socks5: failed to resolve domain name '%s'", domain);
  544. failed=true;
  545. return false;
  546. }
  547. }else if(atyp==4){
  548. unsigned char addr[16];
  549. in.ReadBytes(addr, 16);
  550. connectedAddress=new IPv6Address(addr);
  551. }else{
  552. LOGW("socks5: unknown address type %d", atyp);
  553. failed=true;
  554. return false;
  555. }
  556. connectedPort=(uint16_t)ntohs(in.ReadInt16());
  557. state=ConnectionState::Connected;
  558. readyToSend=true;
  559. LOGV("socks5: udp associate successful, given endpoint %s:%d", connectedAddress->ToString().c_str(), connectedPort);
  560. }catch(std::out_of_range&){
  561. LOGW("socks5: udp associate response parse failed");
  562. failed=true;
  563. }
  564. }
  565. }
  566. return udp ? udp->OnReadyToReceive() : tcp->OnReadyToReceive();
  567. }
  568. void NetworkSocketSOCKS5Proxy::SendConnectionCommand(){
  569. unsigned char buf[1024];
  570. if(protocol==PROTO_TCP){
  571. BufferOutputStream out(buf, sizeof(buf));
  572. out.WriteByte(5); // VER
  573. out.WriteByte(1); // CMD (CONNECT)
  574. out.WriteByte(0); // RSV
  575. const IPv4Address* v4=dynamic_cast<const IPv4Address*>(connectedAddress);
  576. const IPv6Address* v6=dynamic_cast<const IPv6Address*>(connectedAddress);
  577. if(v4){
  578. out.WriteByte(1); // ATYP (IPv4)
  579. out.WriteInt32(v4->GetAddress());
  580. }else if(v6){
  581. out.WriteByte(4); // ATYP (IPv6)
  582. out.WriteBytes((unsigned char*)v6->GetAddress(), 16);
  583. }else{
  584. LOGW("socks5: unknown address type");
  585. failed=true;
  586. return;
  587. }
  588. out.WriteInt16(htons(connectedPort)); // DST.PORT
  589. tcp->Send(buf, out.GetLength());
  590. state=ConnectionState::WaitingForCommandResult;
  591. }else if(protocol==PROTO_UDP){
  592. LOGV("Sending udp associate");
  593. BufferOutputStream out(buf, sizeof(buf));
  594. out.WriteByte(5); // VER
  595. out.WriteByte(3); // CMD (UDP ASSOCIATE)
  596. out.WriteByte(0); // RSV
  597. out.WriteByte(1); // ATYP (IPv4)
  598. out.WriteInt32(0); // DST.ADDR
  599. out.WriteInt16(0); // DST.PORT
  600. tcp->Send(buf, out.GetLength());
  601. state=ConnectionState::WaitingForCommandResult;
  602. }
  603. }
  604. bool NetworkSocketSOCKS5Proxy::NeedSelectForSending(){
  605. return state==ConnectionState::Initial || state==ConnectionState::Connected;
  606. }