network.c 25 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067
  1. #ifndef CONFIG
  2. #define CONFIG "config.h"
  3. #endif // CONFIG
  4. #include CONFIG
  5. #ifndef USE_MSRPC
  6. #ifndef _GNU_SOURCE
  7. #define _GNU_SOURCE
  8. #endif
  9. #include "types.h"
  10. #if HAVE_GETIFADDR && _WIN32
  11. #include <iphlpapi.h>
  12. #endif
  13. #include <string.h>
  14. #ifndef _WIN32
  15. #include <signal.h>
  16. #include <unistd.h>
  17. #include <fcntl.h>
  18. #include <errno.h>
  19. #include <netinet/in.h>
  20. #include <sys/types.h>
  21. #if HAVE_GETIFADDR
  22. #if __ANDROID__
  23. #include "ifaddrs-android.h"
  24. #elif defined(GETIFADDRS_MUSL)
  25. #include "ifaddrs-musl.h"
  26. #else // getifaddrs from OS
  27. #include <ifaddrs.h>
  28. #endif // getifaddrs from OS
  29. #endif // HAVE_GETIFADDR
  30. #endif // !WIN32
  31. #include "network.h"
  32. #include "endian.h"
  33. //#include "output.h"
  34. #include "helpers.h"
  35. #include "shared_globals.h"
  36. #include "rpc.h"
  37. #ifndef _WIN32
  38. typedef ssize_t(*sendrecv_t)(int, void*, size_t, int);
  39. #else
  40. typedef int (WINAPI *sendrecv_t)(SOCKET, void*, int, int);
  41. #endif
  42. // Send or receive a fixed number of bytes regardless if received in one or more chunks
  43. int_fast8_t sendrecv(SOCKET sock, BYTE *data, int len, int_fast8_t do_send)
  44. {
  45. int n;
  46. sendrecv_t f = do_send
  47. ? (sendrecv_t)send
  48. : (sendrecv_t)recv;
  49. do
  50. {
  51. n = f(sock, data, len, 0);
  52. } while (
  53. (n < 0 && socket_errno == SOCKET_EINTR) || (n > 0 && (data += n, (len -= n) > 0)));
  54. return !len;
  55. }
  56. static int_fast8_t ip2str(char *restrict result, const size_t resultLength, const struct sockaddr *const restrict socketAddress, const socklen_t socketLength)
  57. {
  58. static const char *const fIPv4 = "%s:%s";
  59. static const char *const fIPv6 = "[%s]:%s";
  60. char ipAddress[64], portNumber[8];
  61. if (getnameinfo
  62. (
  63. socketAddress,
  64. socketLength,
  65. ipAddress,
  66. sizeof(ipAddress),
  67. portNumber,
  68. sizeof(portNumber),
  69. NI_NUMERICHOST | NI_NUMERICSERV
  70. ))
  71. {
  72. return FALSE;
  73. }
  74. if ((unsigned int)vlmcsd_snprintf(result, resultLength, socketAddress->sa_family == AF_INET6 ? fIPv6 : fIPv4, ipAddress, portNumber) > resultLength) return FALSE;
  75. return TRUE;
  76. }
  77. static int_fast8_t getSocketList(struct addrinfo **saList, const char *const addr, const int flags, const int AddressFamily)
  78. {
  79. int status;
  80. char *szHost, *szPort;
  81. size_t len = strlen(addr) + 1;
  82. // Don't alloca too much
  83. if (len > 264) return FALSE;
  84. char *addrcopy = (char*)alloca(len);
  85. memcpy(addrcopy, addr, len);
  86. parseAddress(addrcopy, &szHost, &szPort);
  87. struct addrinfo hints;
  88. memset(&hints, 0, sizeof(struct addrinfo));
  89. hints.ai_family = AddressFamily;
  90. hints.ai_socktype = SOCK_STREAM;
  91. hints.ai_protocol = IPPROTO_TCP;
  92. hints.ai_flags = flags;
  93. if ((status = getaddrinfo(szHost, szPort, &hints, saList)))
  94. {
  95. printerrorf("Warning: %s: %s\n", addr, gai_strerror(status));
  96. return FALSE;
  97. }
  98. return TRUE;
  99. }
  100. static int_fast8_t setBlockingEnabled(SOCKET fd, int_fast8_t blocking)
  101. {
  102. if (fd == INVALID_SOCKET) return FALSE;
  103. #ifdef _WIN32
  104. unsigned long mode = blocking ? 0 : 1;
  105. return (ioctlsocket(fd, FIONBIO, &mode) == 0) ? TRUE : FALSE;
  106. #else // POSIX
  107. int flags = fcntl(fd, F_GETFL, 0);
  108. if (flags < 0) return FALSE;
  109. flags = blocking ? (flags & ~O_NONBLOCK) : (flags | O_NONBLOCK);
  110. return (fcntl(fd, F_SETFL, flags) == 0) ? TRUE : FALSE;
  111. #endif // POSIX
  112. }
  113. int_fast8_t isDisconnected(const SOCKET s)
  114. {
  115. char buffer[1];
  116. if (!setBlockingEnabled(s, FALSE)) return TRUE;
  117. int n = recv(s, buffer, 1, MSG_PEEK);
  118. if (!setBlockingEnabled(s, TRUE)) return TRUE;
  119. if (n == 0) return TRUE;
  120. return FALSE;
  121. }
  122. #if !defined(NO_PRIVATE_IP_DETECT)
  123. // Check, if a sockaddr is a private IPv4 or IPv6 address
  124. static int_fast8_t isPrivateIPAddress(struct sockaddr* addr, socklen_t* length)
  125. {
  126. union v6addr
  127. {
  128. uint8_t bytes[16];
  129. uint16_t words[8];
  130. uint32_t dwords[4];
  131. uint64_t qwords[2];
  132. };
  133. if (addr == NULL) return FALSE;
  134. switch (addr->sa_family)
  135. {
  136. case AF_INET6:
  137. {
  138. union v6addr* ipv6addr = (union v6addr*)&((struct sockaddr_in6*)addr)->sin6_addr;
  139. if
  140. (
  141. (ipv6addr->qwords[0] != 0 || BE64(ipv6addr->qwords[1]) != 1) && // ::1 IPv6 localhost
  142. (BE16(ipv6addr->words[0]) & 0xe000) == 0x2000 // !2000::/3
  143. )
  144. {
  145. return FALSE;
  146. }
  147. if (length) *length = sizeof(struct sockaddr_in6);
  148. break;
  149. }
  150. case AF_INET:
  151. {
  152. uint32_t ipv4addr = BE32(((struct sockaddr_in*)addr)->sin_addr.s_addr);
  153. if
  154. (
  155. (ipv4addr & 0xff000000) != 0x7f000000 && // 127.x.x.x localhost
  156. (ipv4addr & 0xffff0000) != 0xc0a80000 && // 192.168.x.x private routeable
  157. (ipv4addr & 0xffff0000) != 0xa9fe0000 && // 169.254.x.x link local
  158. (ipv4addr & 0xff000000) != 0x0a000000 && // 10.x.x.x private routeable
  159. (ipv4addr & 0xfff00000) != 0xac100000 // 172.16-31.x.x private routeable
  160. )
  161. {
  162. return FALSE;
  163. }
  164. if (length) *length = sizeof(struct sockaddr_in);
  165. break;
  166. }
  167. default:
  168. return FALSE;
  169. }
  170. return TRUE;
  171. }
  172. #endif // !defined(NO_PRIVATE_IP_DETECT)
  173. // Connect to TCP address addr (e.g. "kms.example.com:1688") and return an
  174. // open socket for the connection if successful or INVALID_SOCKET otherwise
  175. SOCKET connectToAddress(const char *const addr, const int AddressFamily, int_fast8_t showHostName)
  176. {
  177. struct addrinfo *saList, *sa;
  178. SOCKET s = INVALID_SOCKET;
  179. char szAddr[128];
  180. if (!getSocketList(&saList, addr, 0, AddressFamily)) return INVALID_SOCKET;
  181. for (sa = saList; sa; sa = sa->ai_next)
  182. {
  183. // struct sockaddr_in* addr4 = (struct sockaddr_in*)sa->ai_addr;
  184. // struct sockaddr_in6* addr6 = (struct sockaddr_in6*)sa->ai_addr;
  185. if (ip2str(szAddr, sizeof(szAddr), sa->ai_addr, (socklen_t)sa->ai_addrlen))
  186. {
  187. if (showHostName)
  188. printf("Connecting to %s (%s) ... ", addr, szAddr);
  189. else
  190. printf("Connecting to %s ... ", szAddr);
  191. fflush(stdout);
  192. }
  193. s = socket(sa->ai_family, SOCK_STREAM, IPPROTO_TCP);
  194. # if !defined(NO_TIMEOUT) && !__minix__
  195. # ifndef _WIN32 // Standard Posix timeout structure
  196. struct timeval to;
  197. to.tv_sec = 10;
  198. to.tv_usec = 0;
  199. # else // Windows requires a DWORD with milliseconds
  200. DWORD to = 10000;
  201. # endif // _WIN32
  202. setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (sockopt_t)&to, sizeof(to));
  203. setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, (sockopt_t)&to, sizeof(to));
  204. # endif // !defined(NO_TIMEOUT) && !__minix__
  205. if (!connect(s, sa->ai_addr, (int)sa->ai_addrlen))
  206. {
  207. printf("successful\n");
  208. break;
  209. }
  210. printerrorf("%s: %s\n", szAddr, socket_errno == SOCKET_EINPROGRESS ? "Timed out" : vlmcsd_strerror(socket_errno));
  211. socketclose(s);
  212. s = INVALID_SOCKET;
  213. }
  214. freeaddrinfo(saList);
  215. return s;
  216. }
  217. // fix for lame tomato toolchain
  218. # if !defined(IPV6_V6ONLY) && defined(__linux__)
  219. # define IPV6_V6ONLY (26)
  220. # endif // !defined(IPV6_V6ONLY) && defined(__linux__)
  221. #ifndef NO_SOCKETS
  222. static int_fast8_t allowSocketReuse(SOCKET s)
  223. {
  224. # if !__CYGWIN__
  225. BOOL socketOption = TRUE;
  226. # if !_WIN32
  227. # define VLMCSD_SOCKET_OPTION SO_REUSEADDR
  228. # else // _WIN32
  229. # define VLMCSD_SOCKET_OPTION SO_EXCLUSIVEADDRUSE
  230. # endif // _WIN32
  231. if (setsockopt(s, SOL_SOCKET, VLMCSD_SOCKET_OPTION, (sockopt_t)&socketOption, sizeof(socketOption)))
  232. {
  233. # ifdef _PEDANTIC
  234. printerrorf("Warning: Socket option SO_REUSEADDR unsupported: %s\n", vlmcsd_strerror(socket_errno));
  235. # endif // _PEDANTIC
  236. }
  237. # undef VLMCSD_SOCKET_OPTION
  238. # endif // !__CYGWIN__
  239. return 0;
  240. }
  241. #ifdef SIMPLE_SOCKETS
  242. int listenOnAllAddresses()
  243. {
  244. uint32_t port_listen;
  245. if (!stringToInt(defaultport, 1, 65535, &port_listen))
  246. {
  247. printerrorf("Fatal: Port must be numeric between 1 and 65535.\n");
  248. exit(VLMCSD_EINVAL);
  249. }
  250. # if defined(AF_INET6) && defined(IPV6_V6ONLY)
  251. struct sockaddr_in6 addr;
  252. memset(&addr, 0, sizeof(addr));
  253. addr.sin6_family = AF_INET6;
  254. addr.sin6_port = BE16((uint16_t)port_listen);
  255. addr.sin6_addr = in6addr_any;
  256. BOOL v6only = FALSE;
  257. s_server = socket(AF_INET6, SOCK_STREAM, 0);
  258. if (s_server == INVALID_SOCKET
  259. || allowSocketReuse(s_server)
  260. || setsockopt(s_server, IPPROTO_IPV6, IPV6_V6ONLY, (sockopt_t)&v6only, sizeof(v6only))
  261. || bind(s_server, (struct sockaddr *)&addr, sizeof(addr))
  262. || listen(s_server, SOMAXCONN))
  263. {
  264. socketclose(s_server);
  265. # endif // defined(AF_INET6) && defined(IPV6_V6ONLY)
  266. struct sockaddr_in addr4 = {
  267. .sin_family = AF_INET,
  268. .sin_port = BE16((uint16_t)port_listen),
  269. .sin_addr.s_addr = BE32(INADDR_ANY)
  270. };
  271. s_server = socket(AF_INET, SOCK_STREAM, 0);
  272. if (s_server == INVALID_SOCKET
  273. || allowSocketReuse(s_server)
  274. || bind(s_server, (struct sockaddr *)&addr4, sizeof(addr4))
  275. || listen(s_server, SOMAXCONN))
  276. {
  277. int error = socket_errno;
  278. printerrorf("Fatal: Cannot bind to TCP port %u: %s\n", port_listen, vlmcsd_strerror(error));
  279. return error;
  280. }
  281. # if defined(AF_INET6) && defined(IPV6_V6ONLY)
  282. }
  283. # endif // defined(AF_INET6) && defined(IPV6_V6ONLY)
  284. #ifndef NO_LOG
  285. logger("Listening on TCP port %u\n", port_listen);
  286. #endif // NO_LOG
  287. return 0;
  288. }
  289. #else // !SIMPLE_SOCKETS
  290. #if HAVE_GETIFADDR && !defined(NO_PRIVATE_IP_DETECT)
  291. // Get list of private IP addresses.
  292. // Returns 0 on success or an errno error code on failure
  293. void getPrivateIPAddresses(int* numAddresses, char*** ipAddresses)
  294. {
  295. # if _WIN32
  296. PIP_ADAPTER_ADDRESSES firstAdapter, currentAdapter;
  297. DWORD dwRetVal;
  298. ULONG outBufLen = 16384;
  299. ULONG flags = GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_SKIP_FRIENDLY_NAME;
  300. firstAdapter = (PIP_ADAPTER_ADDRESSES)vlmcsd_malloc(outBufLen);
  301. if ((dwRetVal = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, firstAdapter, &outBufLen)) == ERROR_BUFFER_OVERFLOW)
  302. {
  303. free(firstAdapter);
  304. firstAdapter = (PIP_ADAPTER_ADDRESSES)vlmcsd_malloc(outBufLen);
  305. dwRetVal = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, firstAdapter, &outBufLen);
  306. }
  307. if (dwRetVal != NO_ERROR)
  308. {
  309. printerrorf("FATAL: Could not get network address list: %s\n", vlmcsd_strerror(dwRetVal));
  310. exit(dwRetVal);
  311. }
  312. for (currentAdapter = firstAdapter, *numAddresses = 0; currentAdapter != NULL; currentAdapter = currentAdapter->Next)
  313. {
  314. PIP_ADAPTER_UNICAST_ADDRESS currentAddress;
  315. int length;
  316. if (currentAdapter->OperStatus != IfOperStatusUp) continue;
  317. for (currentAddress = currentAdapter->FirstUnicastAddress; currentAddress != NULL; currentAddress = currentAddress->Next)
  318. {
  319. if (isPrivateIPAddress(currentAddress->Address.lpSockaddr, &length)) (*numAddresses)++;
  320. }
  321. }
  322. *ipAddresses = (char**)vlmcsd_malloc(*numAddresses * sizeof(char*));
  323. for (currentAdapter = firstAdapter, *numAddresses = 0; currentAdapter != NULL; currentAdapter = currentAdapter->Next)
  324. {
  325. PIP_ADAPTER_UNICAST_ADDRESS currentAddress;
  326. int length;
  327. if (currentAdapter->OperStatus != IfOperStatusUp) continue;
  328. for (currentAddress = currentAdapter->FirstUnicastAddress; currentAddress != NULL; currentAddress = currentAddress->Next)
  329. {
  330. if (!isPrivateIPAddress(currentAddress->Address.lpSockaddr, &length)) continue;
  331. char *ipAddress = (char*)vlmcsd_malloc(64);
  332. int error = getnameinfo(currentAddress->Address.lpSockaddr, currentAddress->Address.iSockaddrLength, ipAddress, 64, NULL, 0, NI_NUMERICHOST);
  333. if (error)
  334. {
  335. printerrorf("WARNING: Could not get IP address from interface list: %s\n", gai_strerror(error));
  336. *ipAddress = 0;
  337. }
  338. (*ipAddresses)[(*numAddresses)++] = ipAddress;
  339. }
  340. }
  341. free(firstAdapter);
  342. # else // !_WIN32
  343. struct ifaddrs *addrs, *addr;
  344. if (getifaddrs(&addrs))
  345. {
  346. printerrorf("FATAL: Could not get network address list: %s\n", vlmcsd_strerror(errno));
  347. exit(errno);
  348. }
  349. socklen_t length;
  350. for (addr = addrs, *numAddresses = 0; addr != NULL; addr = addr->ifa_next)
  351. {
  352. if (!isPrivateIPAddress(addr->ifa_addr, &length)) continue;
  353. (*numAddresses)++;
  354. }
  355. *ipAddresses = (char**)vlmcsd_malloc(*numAddresses * sizeof(char*));
  356. for (addr = addrs, *numAddresses = 0; addr != NULL; addr = addr->ifa_next)
  357. {
  358. if (!isPrivateIPAddress(addr->ifa_addr, &length)) continue;
  359. char *ipAddress = (char*)vlmcsd_malloc(64);
  360. int error = getnameinfo(addr->ifa_addr, length, ipAddress, 64, NULL, 0, NI_NUMERICHOST);
  361. if (error)
  362. {
  363. printerrorf("WARNING: Could not get IP address from interface list: %s\n", gai_strerror(error));
  364. *ipAddress = 0;
  365. }
  366. # if __UCLIBC__ || __gnu_hurd__
  367. size_t adrlen = strlen(ipAddress);
  368. if
  369. (
  370. addr->ifa_addr->sa_family == AF_INET6 &&
  371. adrlen > 5 &&
  372. !strchr(ipAddress, '%') &&
  373. (BE16(*(uint16_t*)&((struct sockaddr_in6*)addr->ifa_addr)->sin6_addr) & 0xffc0) == 0xfe80
  374. )
  375. {
  376. size_t ifnamelen = strlen(addr->ifa_name);
  377. char* workaroundIpAddress = (char*)vlmcsd_malloc(adrlen + ifnamelen + 2);
  378. strcpy(workaroundIpAddress, ipAddress);
  379. strcat(workaroundIpAddress, "%");
  380. strcat(workaroundIpAddress, addr->ifa_name);
  381. (*ipAddresses)[(*numAddresses)++] = workaroundIpAddress;
  382. free(ipAddress);
  383. }
  384. else
  385. {
  386. (*ipAddresses)[(*numAddresses)++] = ipAddress;
  387. }
  388. # else // !(__UCLIBC__ || __gnu_hurd__)
  389. (*ipAddresses)[(*numAddresses)++] = ipAddress;
  390. # endif // !(__UCLIBC__ || __gnu_hurd__)
  391. }
  392. freeifaddrs(addrs);
  393. # endif // !_WIN32
  394. }
  395. #endif // HAVE_GETIFADDR && !defined(NO_PRIVATE_IP_DETECT)
  396. // Create a Listening socket for addrinfo sa and return socket s
  397. // szHost and szPort are for logging only
  398. static int listenOnAddress(const struct addrinfo *const ai, SOCKET *s)
  399. {
  400. int error;
  401. char ipstr[64];
  402. ip2str(ipstr, sizeof(ipstr), ai->ai_addr, (socklen_t)ai->ai_addrlen);
  403. //*s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
  404. *s = socket(ai->ai_family, SOCK_STREAM, IPPROTO_TCP);
  405. if (*s == INVALID_SOCKET)
  406. {
  407. error = socket_errno;
  408. printerrorf("Warning: %s error. %s\n", ai->ai_family == AF_INET6 ? cIPv6 : cIPv4, vlmcsd_strerror(error));
  409. return error;
  410. }
  411. # if !defined(_WIN32) && !defined(NO_SIGHUP)
  412. int flags = fcntl(*s, F_GETFD, 0);
  413. if (flags != -1)
  414. {
  415. flags |= FD_CLOEXEC;
  416. fcntl(*s, F_SETFD, flags);
  417. }
  418. # ifdef _PEDANTIC
  419. else
  420. {
  421. printerrorf("Warning: Could not set FD_CLOEXEC flag on %s: %s\n", ipstr, vlmcsd_strerror(errno));
  422. }
  423. # endif // _PEDANTIC
  424. # endif // !defined(_WIN32) && !defined(NO_SIGHUP)
  425. BOOL socketOption = TRUE;
  426. # ifdef IPV6_V6ONLY
  427. if (ai->ai_family == AF_INET6 && setsockopt(*s, IPPROTO_IPV6, IPV6_V6ONLY, (sockopt_t)&socketOption, sizeof(socketOption)))
  428. {
  429. # ifdef _PEDANTIC
  430. # if defined(_WIN32) || defined(__CYGWIN__)
  431. // if (IsWindowsVistaOrGreater()) //Doesn't work with older version of MingW32-w64 toolchain
  432. if ((GetVersion() & 0xff) > 5)
  433. # endif // _WIN32
  434. printerrorf("Warning: %s does not support socket option IPV6_V6ONLY: %s\n", ipstr, vlmcsd_strerror(socket_errno));
  435. # endif // _PEDANTIC
  436. }
  437. # endif
  438. allowSocketReuse(*s);
  439. # if HAVE_FREEBIND
  440. # if (defined(IP_NONLOCALOK) || __FreeBSD_kernel__ || __FreeBSD__) && !defined(IPV6_BINDANY)
  441. # define IPV6_BINDANY 64
  442. # endif // (defined(IP_NONLOCALOK) || __FreeBSD_kernel__ || __FreeBSD__) && !defined(IPV6_BINDANY)
  443. if (freebind)
  444. {
  445. # if defined(IP_FREEBIND) // Linux
  446. if (setsockopt(*s, IPPROTO_IP, IP_FREEBIND, (sockopt_t)&socketOption, sizeof(socketOption)))
  447. {
  448. printerrorf("Warning: Cannot use FREEBIND on %s: %s\n", ipstr, vlmcsd_strerror(socket_errno));
  449. }
  450. # endif // defined(IP_FREEBIND)
  451. # if defined(IP_BINDANY) // FreeBSD IPv4
  452. if (ai->ai_family == AF_INET && setsockopt(*s, IPPROTO_IP, IP_BINDANY, (sockopt_t)&socketOption, sizeof(socketOption)))
  453. {
  454. printerrorf("Warning: Cannot use BINDANY on %s: %s\n", ipstr, vlmcsd_strerror(socket_errno));
  455. }
  456. # endif // defined(IP_BINDANY)
  457. # if defined(IPV6_BINDANY) // FreeBSD IPv6
  458. if (ai->ai_family == AF_INET6 && setsockopt(*s, IPPROTO_IP, IPV6_BINDANY, (sockopt_t)&socketOption, sizeof(socketOption)))
  459. {
  460. # ifdef _PEDANTIC // FreeBSD defines the symbol but doesn't have BINDANY in IPv6 (Kame stack doesn't have it)
  461. printerrorf("Warning: Cannot use BINDANY on %s: %s\n", ipstr, vlmcsd_strerror(socket_errno));
  462. # endif
  463. }
  464. # endif // defined(IPV6_BINDANY)
  465. # if defined(IP_NONLOCALOK) && !defined(IP_BINDANY) // FreeBSD with GNU userspace IPv4
  466. if (ai->ai_family == AF_INET && setsockopt(*s, IPPROTO_IP, IP_NONLOCALOK, (sockopt_t)&socketOption, sizeof(socketOption)))
  467. {
  468. printerrorf("Warning: Cannot use BINDANY on %s: %s\n", ipstr, vlmcsd_strerror(socket_errno));
  469. }
  470. # endif // defined(IP_NONLOCALOK) && !defined(IP_BINDANY)
  471. }
  472. # endif // HAVE_FREEBIND
  473. if (bind(*s, ai->ai_addr, (int)ai->ai_addrlen) || listen(*s, SOMAXCONN))
  474. {
  475. error = socket_errno;
  476. printerrorf("Warning: %s: %s\n", ipstr, vlmcsd_strerror(error));
  477. socketclose(*s);
  478. return error;
  479. }
  480. # ifndef NO_LOG
  481. logger("Listening on %s\n", ipstr);
  482. # endif
  483. return 0;
  484. }
  485. // Adds a listening socket for an address string,
  486. // e.g. 127.0.0.1:1688 or [2001:db8:dead:beef::1]:1688
  487. BOOL addListeningSocket(const char *const addr)
  488. {
  489. struct addrinfo *aiList, *ai;
  490. int result = FALSE;
  491. SOCKET *s = SocketList + numsockets;
  492. if (getSocketList(&aiList, addr, AI_PASSIVE | AI_NUMERICHOST, AF_UNSPEC))
  493. {
  494. for (ai = aiList; ai; ai = ai->ai_next)
  495. {
  496. // struct sockaddr_in* addr4 = (struct sockaddr_in*)sa->ai_addr;
  497. // struct sockaddr_in6* addr6 = (struct sockaddr_in6*)sa->ai_addr;
  498. if (numsockets >= FD_SETSIZE)
  499. {
  500. #ifdef _PEDANTIC // Do not report this error in normal builds to keep file size low
  501. printerrorf("Warning: Cannot listen on %s. Your OS only supports %u listening sockets in an FD_SET.\n", addr, FD_SETSIZE);
  502. #endif
  503. break;
  504. }
  505. if (!listenOnAddress(ai, s))
  506. {
  507. numsockets++;
  508. result = TRUE;
  509. }
  510. }
  511. freeaddrinfo(aiList);
  512. }
  513. return result;
  514. }
  515. // Just create some dummy sockets to see if we have a specific protocol (IPv4 or IPv6)
  516. __pure int_fast8_t checkProtocolStack(const int addressfamily)
  517. {
  518. SOCKET s; // = INVALID_SOCKET;
  519. s = socket(addressfamily, SOCK_STREAM, 0);
  520. int_fast8_t success = (s != INVALID_SOCKET);
  521. socketclose(s);
  522. return success;
  523. }
  524. // Build an fd_set of all listening socket then use select to wait for an incoming connection
  525. static SOCKET network_accept_any()
  526. {
  527. fd_set ListeningSocketsList;
  528. SOCKET maxSocket, sock;
  529. int i;
  530. int status;
  531. FD_ZERO(&ListeningSocketsList);
  532. maxSocket = 0;
  533. for (i = 0; i < numsockets; i++)
  534. {
  535. FD_SET(SocketList[i], &ListeningSocketsList);
  536. if (SocketList[i] > maxSocket) maxSocket = SocketList[i];
  537. }
  538. status = select((int)maxSocket + 1, &ListeningSocketsList, NULL, NULL, NULL);
  539. if (status < 0) return INVALID_SOCKET;
  540. sock = INVALID_SOCKET;
  541. for (i = 0; i < numsockets; i++)
  542. {
  543. if (FD_ISSET(SocketList[i], &ListeningSocketsList))
  544. {
  545. sock = SocketList[i];
  546. break;
  547. }
  548. }
  549. if (sock == INVALID_SOCKET)
  550. return INVALID_SOCKET;
  551. else
  552. return accept(sock, NULL, NULL);
  553. }
  554. #endif // !SIMPLE_SOCKETS
  555. void closeAllListeningSockets()
  556. {
  557. # ifdef SIMPLE_SOCKETS
  558. socketclose(s_server);
  559. # else // !SIMPLE_SOCKETS
  560. int i;
  561. for (i = 0; i < numsockets; i++)
  562. {
  563. socketclose(SocketList[i]);
  564. }
  565. #endif // !SIMPLE_SOCKETS
  566. }
  567. #endif // NO_SOCKETS
  568. static void serveClient(const SOCKET s_client, const DWORD RpcAssocGroup)
  569. {
  570. # if !defined(NO_TIMEOUT) && !__minix__
  571. # ifndef _WIN32 // Standard Posix timeout structure
  572. struct timeval to;
  573. to.tv_sec = ServerTimeout;
  574. to.tv_usec = 0;
  575. #else // Windows requires a DWORD with milliseconds
  576. DWORD to = ServerTimeout * 1000;
  577. # endif // _WIN32
  578. # if !defined(NO_LOG) && defined(_PEDANTIC)
  579. int result =
  580. setsockopt(s_client, SOL_SOCKET, SO_RCVTIMEO, (sockopt_t)&to, sizeof(to)) ||
  581. setsockopt(s_client, SOL_SOCKET, SO_SNDTIMEO, (sockopt_t)&to, sizeof(to));
  582. if (result) logger("Warning: Set timeout failed: %s\n", vlmcsd_strerror(socket_errno));
  583. # else // !(!defined(NO_LOG) && defined(_PEDANTIC))
  584. setsockopt(s_client, SOL_SOCKET, SO_RCVTIMEO, (sockopt_t)&to, sizeof(to));
  585. setsockopt(s_client, SOL_SOCKET, SO_SNDTIMEO, (sockopt_t)&to, sizeof(to));
  586. # endif // !(!defined(NO_LOG) && defined(_PEDANTIC))
  587. # endif // !defined(NO_TIMEOUT) && !__minix__
  588. char ipstr[64];
  589. socklen_t len;
  590. struct sockaddr_storage addr;
  591. len = sizeof(addr);
  592. if (getpeername(s_client, (struct sockaddr*)&addr, &len) ||
  593. !ip2str(ipstr, sizeof(ipstr), (struct sockaddr*)&addr, len))
  594. {
  595. # if !defined(NO_LOG) && defined(_PEDANTIC)
  596. logger("Fatal: Cannot determine client's IP address: %s\n", vlmcsd_strerror(errno));
  597. # endif // !defined(NO_LOG) && defined(_PEDANTIC)
  598. socketclose(s_client);
  599. return;
  600. }
  601. # ifndef NO_LOG
  602. const char *const connection_type = addr.ss_family == AF_INET6 ? cIPv6 : cIPv4;
  603. static const char *const cAccepted = "accepted";
  604. static const char *const cClosed = "closed";
  605. static const char *const fIP = "%s connection %s: %s.\n";
  606. logger(fIP, connection_type, cAccepted, ipstr);
  607. #endif // NO_LOG
  608. # if !defined(NO_PRIVATE_IP_DETECT)
  609. if (!(PublicIPProtectionLevel & 2) || isPrivateIPAddress((struct sockaddr*)&addr, NULL))
  610. {
  611. rpcServer(s_client, RpcAssocGroup, ipstr);
  612. }
  613. # ifndef NO_LOG
  614. else
  615. {
  616. logger("Client with public IP address rejected\n");
  617. }
  618. # endif // NO_LOG
  619. # else // defined(NO_PRIVATE_IP_DETECT)
  620. rpcServer(s_client, RpcAssocGroup, ipstr);
  621. # endif // defined(NO_PRIVATE_IP_DETECT)
  622. # ifndef NO_LOG
  623. logger(fIP, connection_type, cClosed, ipstr);
  624. # endif // NO_LOG
  625. socketclose(s_client);
  626. }
  627. #ifndef NO_SOCKETS
  628. static void post_sem(void)
  629. {
  630. #if !defined(NO_LIMIT) && !__minix__
  631. if (!InetdMode && MaxTasks != SEM_VALUE_MAX)
  632. {
  633. semaphore_post(MaxTaskSemaphore);
  634. }
  635. #endif // !defined(NO_LIMIT) && !__minix__
  636. }
  637. static void wait_sem(void)
  638. {
  639. #if !defined(NO_LIMIT) && !__minix__
  640. if (!InetdMode && MaxTasks != SEM_VALUE_MAX)
  641. {
  642. semaphore_wait(MaxTaskSemaphore);
  643. }
  644. #endif // !defined(NO_LIMIT) && !__minix__
  645. }
  646. #endif // NO_SOCKETS
  647. #if defined(USE_THREADS) && !defined(NO_SOCKETS)
  648. #if defined(_WIN32) || defined(__CYGWIN__) // Win32 Threads
  649. static DWORD WINAPI serveClientThreadProc(PCLDATA clData)
  650. #else // Posix threads
  651. static void *serveClientThreadProc(PCLDATA clData)
  652. #endif // Thread proc is identical in WIN32 and Posix threads
  653. {
  654. serveClient(clData->socket, clData->RpcAssocGroup);
  655. free(clData);
  656. post_sem();
  657. return 0;
  658. }
  659. #endif // USE_THREADS
  660. #ifndef NO_SOCKETS
  661. #if defined(USE_THREADS) && (defined(_WIN32) || defined(__CYGWIN__)) // Windows Threads
  662. static int serveClientAsyncWinThreads(PCLDATA thr_CLData)
  663. {
  664. wait_sem();
  665. HANDLE h = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)serveClientThreadProc, thr_CLData, 0, NULL);
  666. if (h)
  667. {
  668. CloseHandle(h);
  669. return NO_ERROR;
  670. }
  671. else
  672. {
  673. socketclose(thr_CLData->socket);
  674. free(thr_CLData);
  675. post_sem();
  676. return GetLastError();
  677. }
  678. }
  679. #endif // defined(USE_THREADS) && defined(_WIN32) // Windows Threads
  680. #if defined(USE_THREADS) && !defined(_WIN32) && !defined(__CYGWIN__) // Posix Threads
  681. static int ServeClientAsyncPosixThreads(const PCLDATA thr_CLData)
  682. {
  683. pthread_t p_thr;
  684. pthread_attr_t attr;
  685. int error;
  686. wait_sem();
  687. // Must set detached state to avoid memory leak
  688. if ((error = pthread_attr_init(&attr)) ||
  689. (error = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED)) ||
  690. (error = pthread_create(&p_thr, &attr, (void * (*)(void *))serveClientThreadProc, thr_CLData)))
  691. {
  692. socketclose(thr_CLData->socket);
  693. free(thr_CLData);
  694. post_sem();
  695. return error;
  696. }
  697. return 0;
  698. }
  699. #endif // defined(USE_THREADS) && !defined(_WIN32) // Posix Threads
  700. #ifndef USE_THREADS // fork() implementation
  701. static void ChildSignalHandler(const int signal)
  702. {
  703. if (signal == SIGHUP) return;
  704. post_sem();
  705. #ifndef NO_LOG
  706. logger("Warning: Child killed/crashed by %s\n", strsignal(signal));
  707. #endif // NO_LOG
  708. exit(ECHILD);
  709. }
  710. static int ServeClientAsyncFork(const SOCKET s_client, const DWORD RpcAssocGroup)
  711. {
  712. int pid;
  713. wait_sem();
  714. if ((pid = fork()) < 0)
  715. {
  716. return errno;
  717. }
  718. else if (pid)
  719. {
  720. // Parent process
  721. socketclose(s_client);
  722. return 0;
  723. }
  724. else
  725. {
  726. // Child process
  727. // Setup a Child Handler for most common termination signals
  728. struct sigaction sa;
  729. sa.sa_flags = 0;
  730. sa.sa_handler = ChildSignalHandler;
  731. static int signallist[] = { SIGHUP, SIGINT, SIGTERM, SIGSEGV, SIGILL, SIGFPE, SIGBUS };
  732. if (!sigemptyset(&sa.sa_mask))
  733. {
  734. uint_fast8_t i;
  735. for (i = 0; i < vlmcsd_countof(signallist); i++)
  736. {
  737. sigaction(signallist[i], &sa, NULL);
  738. }
  739. }
  740. serveClient(s_client, RpcAssocGroup);
  741. post_sem();
  742. exit(0);
  743. }
  744. }
  745. #endif
  746. int serveClientAsync(const SOCKET s_client, const DWORD RpcAssocGroup)
  747. {
  748. #ifndef USE_THREADS // fork() implementation
  749. return ServeClientAsyncFork(s_client, RpcAssocGroup);
  750. #else // threads implementation
  751. PCLDATA thr_CLData = (PCLDATA)vlmcsd_malloc(sizeof(CLDATA));
  752. thr_CLData->socket = s_client;
  753. thr_CLData->RpcAssocGroup = RpcAssocGroup;
  754. #if defined(_WIN32) || defined (__CYGWIN__) // Windows threads
  755. return serveClientAsyncWinThreads(thr_CLData);
  756. #else // Posix Threads
  757. return ServeClientAsyncPosixThreads(thr_CLData);
  758. #endif // Posix Threads
  759. #endif // USE_THREADS
  760. }
  761. #endif // NO_SOCKETS
  762. int runServer()
  763. {
  764. DWORD RpcAssocGroup = rand32();
  765. // If compiled for inetd-only mode just serve the stdin socket
  766. #ifdef NO_SOCKETS
  767. serveClient(STDIN_FILENO, RpcAssocGroup);
  768. return 0;
  769. #else
  770. // In inetd mode just handle the stdin socket
  771. if (InetdMode)
  772. {
  773. serveClient(STDIN_FILENO, RpcAssocGroup);
  774. return 0;
  775. }
  776. for (;;)
  777. {
  778. int error;
  779. SOCKET s_client;
  780. # ifdef SIMPLE_SOCKETS
  781. if ((s_client = accept(s_server, NULL, NULL)) == INVALID_SOCKET)
  782. # else // Standalone mode fully featured sockets
  783. if ((s_client = network_accept_any()) == INVALID_SOCKET)
  784. # endif // Standalone mode fully featured sockets
  785. {
  786. error = socket_errno;
  787. if (error == SOCKET_EINTR || error == SOCKET_ECONNABORTED) continue;
  788. # ifdef _NTSERVICE
  789. if (ServiceShutdown) return 0;
  790. # endif
  791. # ifndef NO_LOG
  792. logger("Fatal: %s\n", vlmcsd_strerror(error));
  793. # endif
  794. return error;
  795. }
  796. RpcAssocGroup++;
  797. # if !defined(NO_LOG) && defined(_PEDANTIC)
  798. if ((error = serveClientAsync(s_client, RpcAssocGroup)))
  799. {
  800. # ifdef USE_THREADS
  801. logger("Warning: Could not create client thread: %s\n", vlmcsd_strerror(error));
  802. # else // !USE_THREADS
  803. logger("Warning: Could not fork client: %s\n", vlmcsd_strerror(error));
  804. # endif // !USE_THREADS
  805. }
  806. # else // NO_LOG || !_PEDANTIC
  807. serveClientAsync(s_client, RpcAssocGroup);
  808. # endif // NO_LOG || !_PEDANTIC
  809. }
  810. # endif // NO_SOCKETS
  811. }
  812. #endif // USE_MSRPC