socket.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613
  1. /*
  2. Minetest
  3. Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU Lesser General Public License as published by
  6. the Free Software Foundation; either version 2.1 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public License along
  13. with this program; if not, write to the Free Software Foundation, Inc.,
  14. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  15. */
  16. #include "socket.h"
  17. #ifdef _WIN32
  18. #ifndef WIN32_LEAN_AND_MEAN
  19. #define WIN32_LEAN_AND_MEAN
  20. #endif
  21. // Without this some of the network functions are not found on mingw
  22. #ifndef _WIN32_WINNT
  23. #define _WIN32_WINNT 0x0501
  24. #endif
  25. #include <windows.h>
  26. #include <winsock2.h>
  27. #include <ws2tcpip.h>
  28. #ifdef _MSC_VER
  29. #pragma comment(lib, "ws2_32.lib")
  30. #endif
  31. typedef SOCKET socket_t;
  32. typedef int socklen_t;
  33. #else
  34. #include <sys/types.h>
  35. #include <sys/socket.h>
  36. #include <netinet/in.h>
  37. #include <fcntl.h>
  38. #include <netdb.h>
  39. #include <unistd.h>
  40. #include <arpa/inet.h>
  41. typedef int socket_t;
  42. #endif
  43. #include "constants.h"
  44. #include "debug.h"
  45. #include "settings.h"
  46. #include "main.h" // for g_settings
  47. #include <stdio.h>
  48. #include <iostream>
  49. #include <stdlib.h>
  50. #include <string.h>
  51. #include <errno.h>
  52. #include <sstream>
  53. #include <iomanip>
  54. #include "util/string.h"
  55. #include "util/numeric.h"
  56. // Set to true to enable verbose debug output
  57. bool socket_enable_debug_output = false;
  58. bool g_sockets_initialized = false;
  59. // Initialize sockets
  60. void sockets_init()
  61. {
  62. #ifdef _WIN32
  63. // Windows needs sockets to be initialized before use
  64. WSADATA WsaData;
  65. if(WSAStartup( MAKEWORD(2,2), &WsaData ) != NO_ERROR)
  66. throw SocketException("WSAStartup failed");
  67. #endif
  68. g_sockets_initialized = true;
  69. }
  70. void sockets_cleanup()
  71. {
  72. #ifdef _WIN32
  73. // On Windows, cleanup sockets after use
  74. WSACleanup();
  75. #endif
  76. }
  77. /*
  78. Address
  79. */
  80. Address::Address()
  81. {
  82. m_addr_family = 0;
  83. memset(&m_address, 0, sizeof(m_address));
  84. m_port = 0;
  85. }
  86. Address::Address(u32 address, u16 port)
  87. {
  88. memset(&m_address, 0, sizeof(m_address));
  89. setAddress(address);
  90. setPort(port);
  91. }
  92. Address::Address(u8 a, u8 b, u8 c, u8 d, u16 port)
  93. {
  94. memset(&m_address, 0, sizeof(m_address));
  95. setAddress(a, b, c, d);
  96. setPort(port);
  97. }
  98. Address::Address(const IPv6AddressBytes * ipv6_bytes, u16 port)
  99. {
  100. memset(&m_address, 0, sizeof(m_address));
  101. setAddress(ipv6_bytes);
  102. setPort(port);
  103. }
  104. // Equality (address family, address and port must be equal)
  105. bool Address::operator==(Address &address)
  106. {
  107. if(address.m_addr_family != m_addr_family || address.m_port != m_port)
  108. return false;
  109. else if(m_addr_family == AF_INET)
  110. {
  111. return m_address.ipv4.sin_addr.s_addr ==
  112. address.m_address.ipv4.sin_addr.s_addr;
  113. }
  114. else if(m_addr_family == AF_INET6)
  115. {
  116. return memcmp(m_address.ipv6.sin6_addr.s6_addr,
  117. address.m_address.ipv6.sin6_addr.s6_addr, 16) == 0;
  118. }
  119. else
  120. return false;
  121. }
  122. bool Address::operator!=(Address &address)
  123. {
  124. return !(*this == address);
  125. }
  126. void Address::Resolve(const char *name)
  127. {
  128. if (!name || name[0] == 0) {
  129. if (m_addr_family == AF_INET) {
  130. setAddress((u32) 0);
  131. } else if (m_addr_family == AF_INET6) {
  132. setAddress((IPv6AddressBytes*) 0);
  133. }
  134. return;
  135. }
  136. struct addrinfo *resolved, hints;
  137. memset(&hints, 0, sizeof(hints));
  138. // Setup hints
  139. hints.ai_socktype = 0;
  140. hints.ai_protocol = 0;
  141. hints.ai_flags = 0;
  142. if(g_settings->getBool("enable_ipv6"))
  143. {
  144. // AF_UNSPEC allows both IPv6 and IPv4 addresses to be returned
  145. hints.ai_family = AF_UNSPEC;
  146. }
  147. else
  148. {
  149. hints.ai_family = AF_INET;
  150. }
  151. // Do getaddrinfo()
  152. int e = getaddrinfo(name, NULL, &hints, &resolved);
  153. if(e != 0)
  154. throw ResolveError(gai_strerror(e));
  155. // Copy data
  156. if(resolved->ai_family == AF_INET)
  157. {
  158. struct sockaddr_in *t = (struct sockaddr_in *) resolved->ai_addr;
  159. m_addr_family = AF_INET;
  160. m_address.ipv4 = *t;
  161. }
  162. else if(resolved->ai_family == AF_INET6)
  163. {
  164. struct sockaddr_in6 *t = (struct sockaddr_in6 *) resolved->ai_addr;
  165. m_addr_family = AF_INET6;
  166. m_address.ipv6 = *t;
  167. }
  168. else
  169. {
  170. freeaddrinfo(resolved);
  171. throw ResolveError("");
  172. }
  173. freeaddrinfo(resolved);
  174. }
  175. // IP address -> textual representation
  176. std::string Address::serializeString() const
  177. {
  178. // windows XP doesnt have inet_ntop, maybe use better func
  179. #ifdef _WIN32
  180. if(m_addr_family == AF_INET)
  181. {
  182. u8 a, b, c, d;
  183. u32 addr;
  184. addr = ntohl(m_address.ipv4.sin_addr.s_addr);
  185. a = (addr & 0xFF000000) >> 24;
  186. b = (addr & 0x00FF0000) >> 16;
  187. c = (addr & 0x0000FF00) >> 8;
  188. d = (addr & 0x000000FF);
  189. return itos(a) + "." + itos(b) + "." + itos(c) + "." + itos(d);
  190. }
  191. else if(m_addr_family == AF_INET6)
  192. {
  193. std::ostringstream os;
  194. for(int i = 0; i < 16; i += 2)
  195. {
  196. u16 section =
  197. (m_address.ipv6.sin6_addr.s6_addr[i] << 8) |
  198. (m_address.ipv6.sin6_addr.s6_addr[i + 1]);
  199. os << std::hex << section;
  200. if(i < 14)
  201. os << ":";
  202. }
  203. return os.str();
  204. }
  205. else
  206. return std::string("");
  207. #else
  208. char str[INET6_ADDRSTRLEN];
  209. if (inet_ntop(m_addr_family, (m_addr_family == AF_INET) ? (void*)&(m_address.ipv4.sin_addr) : (void*)&(m_address.ipv6.sin6_addr), str, INET6_ADDRSTRLEN) == NULL) {
  210. return std::string("");
  211. }
  212. return std::string(str);
  213. #endif
  214. }
  215. struct sockaddr_in Address::getAddress() const
  216. {
  217. return m_address.ipv4; // NOTE: NO PORT INCLUDED, use getPort()
  218. }
  219. struct sockaddr_in6 Address::getAddress6() const
  220. {
  221. return m_address.ipv6; // NOTE: NO PORT INCLUDED, use getPort()
  222. }
  223. u16 Address::getPort() const
  224. {
  225. return m_port;
  226. }
  227. int Address::getFamily() const
  228. {
  229. return m_addr_family;
  230. }
  231. bool Address::isIPv6() const
  232. {
  233. return m_addr_family == AF_INET6;
  234. }
  235. bool Address::isZero() const
  236. {
  237. if (m_addr_family == AF_INET) {
  238. return m_address.ipv4.sin_addr.s_addr == 0;
  239. } else if (m_addr_family == AF_INET6) {
  240. static const char zero[16] = {0};
  241. return memcmp(m_address.ipv6.sin6_addr.s6_addr,
  242. zero, 16) == 0;
  243. }
  244. return false;
  245. }
  246. void Address::setAddress(u32 address)
  247. {
  248. m_addr_family = AF_INET;
  249. m_address.ipv4.sin_family = AF_INET;
  250. m_address.ipv4.sin_addr.s_addr = htonl(address);
  251. }
  252. void Address::setAddress(u8 a, u8 b, u8 c, u8 d)
  253. {
  254. m_addr_family = AF_INET;
  255. m_address.ipv4.sin_family = AF_INET;
  256. u32 addr = htonl((a << 24) | (b << 16) | (c << 8) | d);
  257. m_address.ipv4.sin_addr.s_addr = addr;
  258. }
  259. void Address::setAddress(const IPv6AddressBytes * ipv6_bytes)
  260. {
  261. m_addr_family = AF_INET6;
  262. m_address.ipv6.sin6_family = AF_INET6;
  263. if(ipv6_bytes)
  264. memcpy(m_address.ipv6.sin6_addr.s6_addr, ipv6_bytes->bytes, 16);
  265. else
  266. memset(m_address.ipv6.sin6_addr.s6_addr, 0, 16);
  267. }
  268. void Address::setPort(u16 port)
  269. {
  270. m_port = port;
  271. }
  272. void Address::print(std::ostream *s) const
  273. {
  274. if(m_addr_family == AF_INET6)
  275. {
  276. (*s) << "[" << serializeString() << "]:" << m_port;
  277. }
  278. else
  279. {
  280. (*s) << serializeString() << ":" << m_port;
  281. }
  282. }
  283. /*
  284. UDPSocket
  285. */
  286. UDPSocket::UDPSocket(bool ipv6)
  287. {
  288. if(g_sockets_initialized == false)
  289. throw SocketException("Sockets not initialized");
  290. // Use IPv6 if specified
  291. m_addr_family = ipv6 ? AF_INET6 : AF_INET;
  292. m_handle = socket(m_addr_family, SOCK_DGRAM, IPPROTO_UDP);
  293. if(socket_enable_debug_output)
  294. {
  295. dstream << "UDPSocket(" << (int) m_handle
  296. << ")::UDPSocket(): ipv6 = "
  297. << (ipv6 ? "true" : "false")
  298. << std::endl;
  299. }
  300. if(m_handle <= 0)
  301. {
  302. throw SocketException("Failed to create socket");
  303. }
  304. setTimeoutMs(0);
  305. }
  306. UDPSocket::~UDPSocket()
  307. {
  308. if(socket_enable_debug_output)
  309. {
  310. dstream << "UDPSocket( " << (int) m_handle << ")::~UDPSocket()"
  311. << std::endl;
  312. }
  313. #ifdef _WIN32
  314. closesocket(m_handle);
  315. #else
  316. close(m_handle);
  317. #endif
  318. }
  319. void UDPSocket::Bind(Address addr)
  320. {
  321. if(socket_enable_debug_output)
  322. {
  323. dstream << "UDPSocket(" << (int) m_handle << ")::Bind(): "
  324. << addr.serializeString() << ":"
  325. << addr.getPort() << std::endl;
  326. }
  327. if (addr.getFamily() != m_addr_family)
  328. {
  329. char errmsg[] = "Socket and bind address families do not match";
  330. errorstream << "Bind failed: " << errmsg << std::endl;
  331. throw SocketException(errmsg);
  332. }
  333. if(m_addr_family == AF_INET6)
  334. {
  335. struct sockaddr_in6 address;
  336. memset(&address, 0, sizeof(address));
  337. address = addr.getAddress6();
  338. address.sin6_family = AF_INET6;
  339. address.sin6_port = htons(addr.getPort());
  340. if(bind(m_handle, (const struct sockaddr *) &address,
  341. sizeof(struct sockaddr_in6)) < 0)
  342. {
  343. dstream << (int) m_handle << ": Bind failed: "
  344. << strerror(errno) << std::endl;
  345. throw SocketException("Failed to bind socket");
  346. }
  347. }
  348. else
  349. {
  350. struct sockaddr_in address;
  351. memset(&address, 0, sizeof(address));
  352. address = addr.getAddress();
  353. address.sin_family = AF_INET;
  354. address.sin_port = htons(addr.getPort());
  355. if(bind(m_handle, (const struct sockaddr *) &address,
  356. sizeof(struct sockaddr_in)) < 0)
  357. {
  358. dstream << (int) m_handle << ": Bind failed: "
  359. << strerror(errno) << std::endl;
  360. throw SocketException("Failed to bind socket");
  361. }
  362. }
  363. }
  364. void UDPSocket::Send(const Address & destination, const void * data, int size)
  365. {
  366. bool dumping_packet = false; // for INTERNET_SIMULATOR
  367. if(INTERNET_SIMULATOR)
  368. dumping_packet = (myrand() % INTERNET_SIMULATOR_PACKET_LOSS == 0);
  369. if(socket_enable_debug_output)
  370. {
  371. // Print packet destination and size
  372. dstream << (int) m_handle << " -> ";
  373. destination.print(&dstream);
  374. dstream << ", size=" << size;
  375. // Print packet contents
  376. dstream << ", data=";
  377. for(int i = 0; i < size && i < 20; i++)
  378. {
  379. if(i % 2 == 0)
  380. dstream << " ";
  381. unsigned int a = ((const unsigned char *) data)[i];
  382. dstream << std::hex << std::setw(2) << std::setfill('0')
  383. << a;
  384. }
  385. if(size > 20)
  386. dstream << "...";
  387. if(dumping_packet)
  388. dstream << " (DUMPED BY INTERNET_SIMULATOR)";
  389. dstream << std::endl;
  390. }
  391. if(dumping_packet)
  392. {
  393. // Lol let's forget it
  394. dstream << "UDPSocket::Send(): "
  395. "INTERNET_SIMULATOR: dumping packet."
  396. << std::endl;
  397. return;
  398. }
  399. if(destination.getFamily() != m_addr_family)
  400. throw SendFailedException("Address family mismatch");
  401. int sent;
  402. if(m_addr_family == AF_INET6)
  403. {
  404. struct sockaddr_in6 address = destination.getAddress6();
  405. address.sin6_port = htons(destination.getPort());
  406. sent = sendto(m_handle, (const char *) data, size,
  407. 0, (struct sockaddr *) &address, sizeof(struct sockaddr_in6));
  408. }
  409. else
  410. {
  411. struct sockaddr_in address = destination.getAddress();
  412. address.sin_port = htons(destination.getPort());
  413. sent = sendto(m_handle, (const char *) data, size,
  414. 0, (struct sockaddr *) &address, sizeof(struct sockaddr_in));
  415. }
  416. if(sent != size)
  417. {
  418. throw SendFailedException("Failed to send packet");
  419. }
  420. }
  421. int UDPSocket::Receive(Address & sender, void * data, int size)
  422. {
  423. // Return on timeout
  424. if(WaitData(m_timeout_ms) == false)
  425. {
  426. return -1;
  427. }
  428. int received;
  429. if(m_addr_family == AF_INET6)
  430. {
  431. struct sockaddr_in6 address;
  432. memset(&address, 0, sizeof(address));
  433. socklen_t address_len = sizeof(address);
  434. received = recvfrom(m_handle, (char *) data,
  435. size, 0, (struct sockaddr *) &address, &address_len);
  436. if(received < 0)
  437. return -1;
  438. u16 address_port = ntohs(address.sin6_port);
  439. IPv6AddressBytes bytes;
  440. memcpy(bytes.bytes, address.sin6_addr.s6_addr, 16);
  441. sender = Address(&bytes, address_port);
  442. }
  443. else
  444. {
  445. struct sockaddr_in address;
  446. memset(&address, 0, sizeof(address));
  447. socklen_t address_len = sizeof(address);
  448. received = recvfrom(m_handle, (char *) data,
  449. size, 0, (struct sockaddr *) &address, &address_len);
  450. if(received < 0)
  451. return -1;
  452. u32 address_ip = ntohl(address.sin_addr.s_addr);
  453. u16 address_port = ntohs(address.sin_port);
  454. sender = Address(address_ip, address_port);
  455. }
  456. if(socket_enable_debug_output)
  457. {
  458. // Print packet sender and size
  459. dstream << (int) m_handle << " <- ";
  460. sender.print(&dstream);
  461. dstream << ", size=" << received;
  462. // Print packet contents
  463. dstream << ", data=";
  464. for(int i = 0; i < received && i < 20; i++)
  465. {
  466. if(i % 2 == 0)
  467. dstream << " ";
  468. unsigned int a = ((const unsigned char *) data)[i];
  469. dstream << std::hex << std::setw(2) << std::setfill('0')
  470. << a;
  471. }
  472. if(received > 20)
  473. dstream << "...";
  474. dstream << std::endl;
  475. }
  476. return received;
  477. }
  478. int UDPSocket::GetHandle()
  479. {
  480. return m_handle;
  481. }
  482. void UDPSocket::setTimeoutMs(int timeout_ms)
  483. {
  484. m_timeout_ms = timeout_ms;
  485. }
  486. bool UDPSocket::WaitData(int timeout_ms)
  487. {
  488. fd_set readset;
  489. int result;
  490. // Initialize the set
  491. FD_ZERO(&readset);
  492. FD_SET(m_handle, &readset);
  493. // Initialize time out struct
  494. struct timeval tv;
  495. tv.tv_sec = 0;
  496. tv.tv_usec = timeout_ms * 1000;
  497. // select()
  498. result = select(m_handle+1, &readset, NULL, NULL, &tv);
  499. if(result == 0)
  500. return false;
  501. else if(result < 0 && (errno == EINTR || errno == EBADF))
  502. // N.B. select() fails when sockets are destroyed on Connection's dtor
  503. // with EBADF. Instead of doing tricky synchronization, allow this
  504. // thread to exit but don't throw an exception.
  505. return false;
  506. else if(result < 0)
  507. {
  508. dstream << (int) m_handle << ": Select failed: "
  509. << strerror(errno) << std::endl;
  510. #ifdef _WIN32
  511. int e = WSAGetLastError();
  512. dstream << (int) m_handle << ": WSAGetLastError()="
  513. << e << std::endl;
  514. if(e == 10004 /* = WSAEINTR */ || e == 10009 /*WSAEBADF*/)
  515. {
  516. dstream << "WARNING: Ignoring WSAEINTR/WSAEBADF." << std::endl;
  517. return false;
  518. }
  519. #endif
  520. throw SocketException("Select failed");
  521. }
  522. else if(FD_ISSET(m_handle, &readset) == false)
  523. {
  524. // No data
  525. return false;
  526. }
  527. // There is data
  528. return true;
  529. }