network.c 25 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055
  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. }
  53. while (
  54. ( n < 0 && socket_errno == VLMCSD_EINTR ) || ( n > 0 && ( data += n, (len -= n) > 0 ) ));
  55. return ! len;
  56. }
  57. static int_fast8_t ip2str(char *restrict result, const size_t resultLength, const struct sockaddr *const restrict socketAddress, const socklen_t socketLength)
  58. {
  59. static const char *const fIPv4 = "%s:%s";
  60. static const char *const fIPv6 = "[%s]:%s";
  61. char ipAddress[64], portNumber[8];
  62. if (getnameinfo
  63. (
  64. socketAddress,
  65. socketLength,
  66. ipAddress,
  67. sizeof(ipAddress),
  68. portNumber,
  69. sizeof(portNumber),
  70. NI_NUMERICHOST | NI_NUMERICSERV
  71. ))
  72. {
  73. return FALSE;
  74. }
  75. if ((unsigned int)snprintf(result, resultLength, socketAddress->sa_family == AF_INET6 ? fIPv6 : fIPv4, ipAddress, portNumber) > resultLength) return FALSE;
  76. return TRUE;
  77. }
  78. static int_fast8_t getSocketList(struct addrinfo **saList, const char *const addr, const int flags, const int AddressFamily)
  79. {
  80. int status;
  81. char *szHost, *szPort;
  82. size_t len = strlen(addr) + 1;
  83. // Don't alloca too much
  84. if (len > 264) return FALSE;
  85. char *addrcopy = (char*)alloca(len);
  86. memcpy(addrcopy, addr, len);
  87. parseAddress(addrcopy, &szHost, &szPort);
  88. struct addrinfo hints;
  89. memset(&hints, 0, sizeof(struct addrinfo));
  90. hints.ai_family = AddressFamily;
  91. hints.ai_socktype = SOCK_STREAM;
  92. hints.ai_protocol = IPPROTO_TCP;
  93. hints.ai_flags = flags;
  94. if ((status = getaddrinfo(szHost, szPort, &hints, saList)))
  95. {
  96. printerrorf("Warning: %s: %s\n", addr, gai_strerror(status));
  97. return FALSE;
  98. }
  99. return TRUE;
  100. }
  101. static int_fast8_t setBlockingEnabled(SOCKET fd, int_fast8_t blocking)
  102. {
  103. if (fd == INVALID_SOCKET) return FALSE;
  104. #ifdef _WIN32
  105. unsigned long mode = blocking ? 0 : 1;
  106. return (ioctlsocket(fd, FIONBIO, &mode) == 0) ? TRUE : FALSE;
  107. #else // POSIX
  108. int flags = fcntl(fd, F_GETFL, 0);
  109. if (flags < 0) return FALSE;
  110. flags = blocking ? (flags & ~O_NONBLOCK) : (flags | O_NONBLOCK);
  111. return (fcntl(fd, F_SETFL, flags) == 0) ? TRUE : FALSE;
  112. #endif // POSIX
  113. }
  114. int_fast8_t isDisconnected(const SOCKET s)
  115. {
  116. char buffer[1];
  117. if (!setBlockingEnabled(s, FALSE)) return TRUE;
  118. int n = recv(s, buffer, 1, MSG_PEEK);
  119. if (!setBlockingEnabled(s, TRUE)) return TRUE;
  120. if (n == 0) return TRUE;
  121. return FALSE;
  122. }
  123. #if !defined(NO_PRIVATE_IP_DETECT)
  124. // Check, if a sockaddr is a private IPv4 or IPv6 address
  125. static int_fast8_t isPrivateIPAddress(struct sockaddr* addr, socklen_t* length)
  126. {
  127. union v6addr
  128. {
  129. uint8_t bytes[16];
  130. uint16_t words[8];
  131. uint32_t dwords[4];
  132. uint64_t qwords[2];
  133. };
  134. if (addr == NULL) return FALSE;
  135. switch (addr->sa_family)
  136. {
  137. case AF_INET6:
  138. {
  139. union v6addr* ipv6addr = (union v6addr*)&((struct sockaddr_in6*)addr)->sin6_addr;
  140. if
  141. (
  142. (ipv6addr->qwords[0] != 0 || BE64(ipv6addr->qwords[1]) != 1) && // ::1 IPv6 localhost
  143. (BE16(ipv6addr->words[0]) & 0xe000) == 0x2000 // !2000::/3
  144. )
  145. {
  146. return FALSE;
  147. }
  148. if (length) *length = sizeof(struct sockaddr_in6);
  149. break;
  150. }
  151. case AF_INET:
  152. {
  153. uint32_t ipv4addr = BE32(((struct sockaddr_in*)addr)->sin_addr.s_addr);
  154. if
  155. (
  156. (ipv4addr & 0xff000000) != 0x7f000000 && // 127.x.x.x localhost
  157. (ipv4addr & 0xffff0000) != 0xc0a80000 && // 192.168.x.x private routeable
  158. (ipv4addr & 0xffff0000) != 0xa9fe0000 && // 169.254.x.x link local
  159. (ipv4addr & 0xff000000) != 0x0a000000 && // 10.x.x.x private routeable
  160. (ipv4addr & 0xfff00000) != 0xac100000 // 172.16-31.x.x private routeable
  161. )
  162. {
  163. return FALSE;
  164. }
  165. if (length) *length = sizeof(struct sockaddr_in);
  166. break;
  167. }
  168. default:
  169. return FALSE;
  170. }
  171. return TRUE;
  172. }
  173. #endif // !defined(NO_PRIVATE_IP_DETECT)
  174. // Connect to TCP address addr (e.g. "kms.example.com:1688") and return an
  175. // open socket for the connection if successful or INVALID_SOCKET otherwise
  176. SOCKET connectToAddress(const char *const addr, const int AddressFamily, int_fast8_t showHostName)
  177. {
  178. struct addrinfo *saList, *sa;
  179. SOCKET s = INVALID_SOCKET;
  180. char szAddr[128];
  181. if (!getSocketList(&saList, addr, 0, AddressFamily)) return INVALID_SOCKET;
  182. for (sa = saList; sa; sa = sa->ai_next)
  183. {
  184. // struct sockaddr_in* addr4 = (struct sockaddr_in*)sa->ai_addr;
  185. // struct sockaddr_in6* addr6 = (struct sockaddr_in6*)sa->ai_addr;
  186. if (ip2str(szAddr, sizeof(szAddr), sa->ai_addr, sa->ai_addrlen))
  187. {
  188. if (showHostName)
  189. printf("Connecting to %s (%s) ... ", addr, szAddr);
  190. else
  191. printf("Connecting to %s ... ", szAddr);
  192. fflush(stdout);
  193. }
  194. s = socket(sa->ai_family, SOCK_STREAM, IPPROTO_TCP);
  195. # if !defined(NO_TIMEOUT) && !__minix__
  196. # ifndef _WIN32 // Standard Posix timeout structure
  197. struct timeval to;
  198. to.tv_sec = 10;
  199. to.tv_usec = 0;
  200. # else // Windows requires a DWORD with milliseconds
  201. DWORD to = 10000;
  202. # endif // _WIN32
  203. setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (sockopt_t)&to, sizeof(to));
  204. setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, (sockopt_t)&to, sizeof(to));
  205. # endif // !defined(NO_TIMEOUT) && !__minix__
  206. if (!connect(s, sa->ai_addr, sa->ai_addrlen))
  207. {
  208. printf("successful\n");
  209. break;
  210. }
  211. printerrorf("%s: %s\n", szAddr, socket_errno == VLMCSD_EINPROGRESS ? "Timed out" : vlmcsd_strerror(socket_errno));
  212. socketclose(s);
  213. s = INVALID_SOCKET;
  214. }
  215. freeaddrinfo(saList);
  216. return s;
  217. }
  218. // fix for lame tomato toolchain
  219. # if !defined(IPV6_V6ONLY) && defined(__linux__)
  220. # define IPV6_V6ONLY (26)
  221. # endif // !defined(IPV6_V6ONLY) && defined(__linux__)
  222. #ifndef NO_SOCKETS
  223. #ifdef SIMPLE_SOCKETS
  224. static int_fast8_t allowSocketReuse(SOCKET s)
  225. {
  226. # if !defined(_WIN32) && !defined(__CYGWIN__)
  227. BOOL socketOption = TRUE;
  228. # else // _WIN32
  229. BOOL socketOption = FALSE;
  230. # endif // _WIN32
  231. if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (sockopt_t)&socketOption, sizeof(socketOption)))
  232. {
  233. # ifdef _PEDANTIC
  234. printerrorf("Warning: %s does not support socket option SO_REUSEADDR: %s\n", ipstr, vlmcsd_strerror(socket_errno));
  235. # endif // _PEDANTIC
  236. }
  237. return 0;
  238. }
  239. int listenOnAllAddresses()
  240. {
  241. uint32_t port_listen;
  242. if (!stringToInt(defaultport, 1, 65535, &port_listen))
  243. {
  244. printerrorf("Fatal: Port must be numeric between 1 and 65535.\n");
  245. exit(!0);
  246. }
  247. struct sockaddr_in6 addr;
  248. memset(&addr, 0, sizeof(addr));
  249. addr.sin6_family = AF_INET6;
  250. addr.sin6_port = BE16((uint16_t)port_listen);
  251. addr.sin6_addr = in6addr_any;
  252. BOOL v6only = FALSE;
  253. s_server = socket(AF_INET6, SOCK_STREAM, 0);
  254. if (s_server == INVALID_SOCKET
  255. || allowSocketReuse(s_server)
  256. || setsockopt(s_server, IPPROTO_IPV6, IPV6_V6ONLY, (sockopt_t)&v6only, sizeof(v6only))
  257. || bind(s_server, (struct sockaddr *)&addr, sizeof(addr))
  258. || listen(s_server, SOMAXCONN) )
  259. {
  260. socketclose(s_server);
  261. struct sockaddr_in addr = {
  262. .sin_family = AF_INET,
  263. .sin_port = BE16((uint16_t)port_listen),
  264. };
  265. addr.sin_addr.s_addr = BE32(INADDR_ANY);
  266. s_server = socket(AF_INET, SOCK_STREAM, 0);
  267. if ( s_server == INVALID_SOCKET
  268. || allowSocketReuse(s_server)
  269. || bind(s_server, (struct sockaddr *)&addr, sizeof(addr))
  270. || listen(s_server, SOMAXCONN) )
  271. {
  272. int error = socket_errno;
  273. printerrorf("Fatal: Cannot bind to TCP port %u: %s\n", port_listen, vlmcsd_strerror(error));
  274. return error;
  275. }
  276. }
  277. #ifndef NO_LOG
  278. logger("Listening on TCP port %u\n", port_listen);
  279. #endif // NO_LOG
  280. return 0;
  281. }
  282. #else // !SIMPLE_SOCKETS
  283. #if HAVE_GETIFADDR && !defined(NO_PRIVATE_IP_DETECT)
  284. // Get list of private IP addresses.
  285. // Returns 0 on success or an errno error code on failure
  286. void getPrivateIPAddresses(int* numAddresses, char*** ipAddresses)
  287. {
  288. # if _WIN32
  289. PIP_ADAPTER_ADDRESSES firstAdapter, currentAdapter;
  290. DWORD dwRetVal = NO_ERROR;
  291. ULONG outBufLen = 16384;
  292. ULONG flags = GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_SKIP_FRIENDLY_NAME;
  293. firstAdapter = (PIP_ADAPTER_ADDRESSES)vlmcsd_malloc(outBufLen);
  294. if ((dwRetVal = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, firstAdapter, &outBufLen)) == ERROR_BUFFER_OVERFLOW)
  295. {
  296. free(firstAdapter);
  297. firstAdapter = (PIP_ADAPTER_ADDRESSES)vlmcsd_malloc(outBufLen);
  298. dwRetVal = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, firstAdapter, &outBufLen);
  299. }
  300. if (dwRetVal != NO_ERROR)
  301. {
  302. printerrorf("FATAL: Could not get network address list: %s\n", vlmcsd_strerror(dwRetVal));
  303. exit(dwRetVal);
  304. }
  305. for (currentAdapter = firstAdapter, *numAddresses = 0; currentAdapter != NULL; currentAdapter = currentAdapter->Next)
  306. {
  307. PIP_ADAPTER_UNICAST_ADDRESS_XP currentAddress;
  308. int length;
  309. if (currentAdapter->OperStatus != IfOperStatusUp) continue;
  310. for (currentAddress = currentAdapter->FirstUnicastAddress; currentAddress != NULL; currentAddress = currentAddress->Next)
  311. {
  312. if (isPrivateIPAddress(currentAddress->Address.lpSockaddr, &length)) (*numAddresses)++;
  313. }
  314. }
  315. *ipAddresses = (char**)vlmcsd_malloc(*numAddresses * sizeof(char*));
  316. for (currentAdapter = firstAdapter, *numAddresses = 0; currentAdapter != NULL; currentAdapter = currentAdapter->Next)
  317. {
  318. PIP_ADAPTER_UNICAST_ADDRESS_XP currentAddress;
  319. int length;
  320. if (currentAdapter->OperStatus != IfOperStatusUp) continue;
  321. for (currentAddress = currentAdapter->FirstUnicastAddress; currentAddress != NULL; currentAddress = currentAddress->Next)
  322. {
  323. if (!isPrivateIPAddress(currentAddress->Address.lpSockaddr, &length)) continue;
  324. char *ipAddress = (char*)vlmcsd_malloc(64);
  325. int error = getnameinfo(currentAddress->Address.lpSockaddr, currentAddress->Address.iSockaddrLength, ipAddress, 64, NULL, 0, NI_NUMERICHOST);
  326. if (error)
  327. {
  328. printerrorf("WARNING: Could not get IP address from interface list: %s\n", gai_strerror(error));
  329. *ipAddress = 0;
  330. }
  331. (*ipAddresses)[(*numAddresses)++] = ipAddress;
  332. }
  333. }
  334. free(firstAdapter);
  335. # else // !_WIN32
  336. struct ifaddrs *addrs, *addr;
  337. if (getifaddrs(&addrs))
  338. {
  339. printerrorf("FATAL: Could not get network address list: %s\n", vlmcsd_strerror(errno));
  340. exit(errno);
  341. }
  342. socklen_t length;
  343. for (addr = addrs, *numAddresses = 0; addr != NULL; addr = addr->ifa_next)
  344. {
  345. if (!isPrivateIPAddress(addr->ifa_addr, &length)) continue;
  346. (*numAddresses)++;
  347. }
  348. *ipAddresses = (char**)vlmcsd_malloc(*numAddresses * sizeof(char*));
  349. for (addr = addrs, *numAddresses = 0; addr != NULL; addr = addr->ifa_next)
  350. {
  351. if (!isPrivateIPAddress(addr->ifa_addr, &length)) continue;
  352. char *ipAddress = (char*)vlmcsd_malloc(64);
  353. int error = getnameinfo(addr->ifa_addr, length, ipAddress, 64, NULL, 0, NI_NUMERICHOST);
  354. if (error)
  355. {
  356. printerrorf("WARNING: Could not get IP address from interface list: %s\n", gai_strerror(error));
  357. *ipAddress = 0;
  358. }
  359. # if __UCLIBC__ || __gnu_hurd__
  360. size_t adrlen = strlen(ipAddress);
  361. if
  362. (
  363. addr->ifa_addr->sa_family == AF_INET6 &&
  364. adrlen > 5 &&
  365. !strchr(ipAddress, '%') &&
  366. (BE16(*(uint16_t*)&((struct sockaddr_in6*)addr->ifa_addr)->sin6_addr) & 0xffc0) == 0xfe80
  367. )
  368. {
  369. size_t ifnamelen = strlen(addr->ifa_name);
  370. char* workaroundIpAddress = (char*)vlmcsd_malloc(adrlen + ifnamelen + 2);
  371. strcpy(workaroundIpAddress, ipAddress);
  372. strcat(workaroundIpAddress, "%");
  373. strcat(workaroundIpAddress, addr->ifa_name);
  374. (*ipAddresses)[(*numAddresses)++] = workaroundIpAddress;
  375. free(ipAddress);
  376. }
  377. else
  378. {
  379. (*ipAddresses)[(*numAddresses)++] = ipAddress;
  380. }
  381. # else // !__UCLIBC__
  382. (*ipAddresses)[(*numAddresses)++] = ipAddress;
  383. # endif // !__UCLIBC__
  384. }
  385. freeifaddrs(addrs);
  386. # endif // !_WIN32
  387. }
  388. #endif // HAVE_GETIFADDR && !defined(NO_PRIVATE_IP_DETECT)
  389. // Create a Listening socket for addrinfo sa and return socket s
  390. // szHost and szPort are for logging only
  391. static int listenOnAddress(const struct addrinfo *const ai, SOCKET *s)
  392. {
  393. int error;
  394. char ipstr[64];
  395. ip2str(ipstr, sizeof(ipstr), ai->ai_addr, ai->ai_addrlen);
  396. //*s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
  397. *s = socket(ai->ai_family, SOCK_STREAM, IPPROTO_TCP);
  398. if (*s == INVALID_SOCKET)
  399. {
  400. error = socket_errno;
  401. printerrorf("Warning: %s error. %s\n", ai->ai_family == AF_INET6 ? cIPv6 : cIPv4, vlmcsd_strerror(error));
  402. return error;
  403. }
  404. # if !defined(_WIN32) && !defined(NO_SIGHUP)
  405. int flags = fcntl(*s, F_GETFD, 0);
  406. if (flags != -1)
  407. {
  408. flags |= FD_CLOEXEC;
  409. fcntl(*s, F_SETFD, flags);
  410. }
  411. # ifdef _PEDANTIC
  412. else
  413. {
  414. printerrorf("Warning: Could not set FD_CLOEXEC flag on %s: %s\n", ipstr, vlmcsd_strerror(errno));
  415. }
  416. # endif // _PEDANTIC
  417. # endif // !defined(_WIN32) && !defined(NO_SIGHUP)
  418. BOOL socketOption = TRUE;
  419. # ifdef IPV6_V6ONLY
  420. if (ai->ai_family == AF_INET6 && setsockopt(*s, IPPROTO_IPV6, IPV6_V6ONLY, (sockopt_t)&socketOption, sizeof(socketOption)))
  421. {
  422. # ifdef _PEDANTIC
  423. # if defined(_WIN32) || defined(__CYGWIN__)
  424. // if (IsWindowsVistaOrGreater()) //Doesn't work with older version of MingW32-w64 toolchain
  425. if ((GetVersion() & 0xff) > 5)
  426. # endif // _WIN32
  427. printerrorf("Warning: %s does not support socket option IPV6_V6ONLY: %s\n", ipstr, vlmcsd_strerror(socket_errno));
  428. # endif // _PEDANTIC
  429. }
  430. # endif
  431. # ifndef _WIN32
  432. if (setsockopt(*s, SOL_SOCKET, SO_REUSEADDR, (sockopt_t)&socketOption, sizeof(socketOption)))
  433. {
  434. # ifdef _PEDANTIC
  435. printerrorf("Warning: %s does not support socket option SO_REUSEADDR: %s\n", ipstr, vlmcsd_strerror(socket_errno));
  436. # endif // _PEDANTIC
  437. }
  438. # endif // _WIN32
  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, 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(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. shutdown(s_server, VLMCSD_SHUT_RDWR);
  559. socketclose(s_server);
  560. # else // !SIMPLE_SOCKETS
  561. int i;
  562. for (i = 0; i < numsockets; i++)
  563. {
  564. shutdown(SocketList[i], VLMCSD_SHUT_RDWR);
  565. socketclose(SocketList[i]);
  566. }
  567. #endif // !SIMPLE_SOCKETS
  568. }
  569. #endif // NO_SOCKETS
  570. static void serveClient(const SOCKET s_client, const DWORD RpcAssocGroup)
  571. {
  572. # if !defined(NO_TIMEOUT) && !__minix__
  573. # ifndef _WIN32 // Standard Posix timeout structure
  574. struct timeval to;
  575. to.tv_sec = ServerTimeout;
  576. to.tv_usec = 0;
  577. #else // Windows requires a DWORD with milliseconds
  578. DWORD to = ServerTimeout * 1000;
  579. # endif // _WIN32
  580. # if !defined(NO_LOG) && defined(_PEDANTIC)
  581. int result =
  582. setsockopt(s_client, SOL_SOCKET, SO_RCVTIMEO, (sockopt_t)&to, sizeof(to)) ||
  583. setsockopt(s_client, SOL_SOCKET, SO_SNDTIMEO, (sockopt_t)&to, sizeof(to));
  584. if (result) logger("Warning: Set timeout failed: %s\n", vlmcsd_strerror(socket_errno));
  585. # else // !(!defined(NO_LOG) && defined(_PEDANTIC))
  586. setsockopt(s_client, SOL_SOCKET, SO_RCVTIMEO, (sockopt_t)&to, sizeof(to));
  587. setsockopt(s_client, SOL_SOCKET, SO_SNDTIMEO, (sockopt_t)&to, sizeof(to));
  588. # endif // !(!defined(NO_LOG) && defined(_PEDANTIC))
  589. # endif // !defined(NO_TIMEOUT) && !__minix__
  590. char ipstr[64];
  591. socklen_t len;
  592. struct sockaddr_storage addr;
  593. len = sizeof addr;
  594. if (getpeername(s_client, (struct sockaddr*)&addr, &len) ||
  595. !ip2str(ipstr, sizeof(ipstr), (struct sockaddr*)&addr, len))
  596. {
  597. # if !defined(NO_LOG) && defined(_PEDANTIC)
  598. logger("Fatal: Cannot determine client's IP address: %s\n", vlmcsd_strerror(errno));
  599. # endif // !defined(NO_LOG) && defined(_PEDANTIC)
  600. socketclose(s_client);
  601. return;
  602. }
  603. # ifndef NO_LOG
  604. const char *const connection_type = addr.ss_family == AF_INET6 ? cIPv6 : cIPv4;
  605. static const char *const cAccepted = "accepted";
  606. static const char *const cClosed = "closed";
  607. static const char *const fIP = "%s connection %s: %s.\n";
  608. logger(fIP, connection_type, cAccepted, ipstr);
  609. #endif // NO_LOG
  610. # if !defined(NO_PRIVATE_IP_DETECT)
  611. if (!(PublicIPProtectionLevel & 2) || isPrivateIPAddress((struct sockaddr*)&addr, NULL))
  612. {
  613. rpcServer(s_client, RpcAssocGroup, ipstr);
  614. }
  615. # ifndef NO_LOG
  616. else
  617. {
  618. logger("Client with public IP address rejected\n");
  619. }
  620. # endif // NO_LOG
  621. # else // defined(NO_PRIVATE_IP_DETECT)
  622. rpcServer(s_client, RpcAssocGroup, ipstr);
  623. # endif // defined(NO_PRIVATE_IP_DETECT)
  624. # ifndef NO_LOG
  625. logger(fIP, connection_type, cClosed, ipstr);
  626. # endif // NO_LOG
  627. socketclose(s_client);
  628. }
  629. #ifndef NO_SOCKETS
  630. static void post_sem(void)
  631. {
  632. #if !defined(NO_LIMIT) && !__minix__
  633. if (!InetdMode && MaxTasks != SEM_VALUE_MAX)
  634. {
  635. semaphore_post(Semaphore);
  636. }
  637. #endif // !defined(NO_LIMIT) && !__minix__
  638. }
  639. static void wait_sem(void)
  640. {
  641. #if !defined(NO_LIMIT) && !__minix__
  642. if (!InetdMode && MaxTasks != SEM_VALUE_MAX)
  643. {
  644. semaphore_wait(Semaphore);
  645. }
  646. #endif // !defined(NO_LIMIT) && !__minix__
  647. }
  648. #endif // NO_SOCKETS
  649. #if defined(USE_THREADS) && !defined(NO_SOCKETS)
  650. #if defined(_WIN32) || defined(__CYGWIN__) // Win32 Threads
  651. static DWORD WINAPI serveClientThreadProc(PCLDATA clData)
  652. #else // Posix threads
  653. static void *serveClientThreadProc (PCLDATA clData)
  654. #endif // Thread proc is identical in WIN32 and Posix threads
  655. {
  656. serveClient(clData->socket, clData->RpcAssocGroup);
  657. free(clData);
  658. post_sem();
  659. return 0;
  660. }
  661. #endif // USE_THREADS
  662. #ifndef NO_SOCKETS
  663. #if defined(USE_THREADS) && (defined(_WIN32) || defined(__CYGWIN__)) // Windows Threads
  664. static int serveClientAsyncWinThreads(const PCLDATA thr_CLData)
  665. {
  666. wait_sem();
  667. HANDLE h = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)serveClientThreadProc, thr_CLData, 0, NULL);
  668. if (h)
  669. CloseHandle(h);
  670. else
  671. {
  672. socketclose(thr_CLData->socket);
  673. free(thr_CLData);
  674. post_sem();
  675. return GetLastError();
  676. }
  677. return NO_ERROR;
  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. wait_sem();
  686. // Must set detached state to avoid memory leak
  687. if (pthread_attr_init(&attr) ||
  688. pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) ||
  689. pthread_create(&p_thr, &attr, (void * (*)(void *))serveClientThreadProc, thr_CLData))
  690. {
  691. socketclose(thr_CLData->socket);
  692. free(thr_CLData);
  693. post_sem();
  694. return !0;
  695. }
  696. return 0;
  697. }
  698. #endif // defined(USE_THREADS) && !defined(_WIN32) // Posix Threads
  699. #ifndef USE_THREADS // fork() implementation
  700. static void ChildSignalHandler(const int signal)
  701. {
  702. if (signal == SIGHUP) return;
  703. post_sem();
  704. #ifndef NO_LOG
  705. logger("Warning: Child killed/crashed by %s\n", strsignal(signal));
  706. #endif // NO_LOG
  707. exit(!0);
  708. }
  709. static int ServeClientAsyncFork(const SOCKET s_client, const DWORD RpcAssocGroup)
  710. {
  711. int pid;
  712. wait_sem();
  713. if ((pid = fork()) < 0)
  714. {
  715. return errno;
  716. }
  717. else if ( pid )
  718. {
  719. // Parent process
  720. socketclose(s_client);
  721. return 0;
  722. }
  723. else
  724. {
  725. // Child process
  726. // Setup a Child Handler for most common termination signals
  727. struct sigaction sa;
  728. sa.sa_flags = 0;
  729. sa.sa_handler = ChildSignalHandler;
  730. static int signallist[] = { SIGHUP, SIGINT, SIGTERM, SIGSEGV, SIGILL, SIGFPE, SIGBUS };
  731. if (!sigemptyset(&sa.sa_mask))
  732. {
  733. uint_fast8_t i;
  734. for (i = 0; i < _countof(signallist); i++)
  735. {
  736. sigaction(signallist[i], &sa, NULL);
  737. }
  738. }
  739. serveClient(s_client, RpcAssocGroup);
  740. post_sem();
  741. exit(0);
  742. }
  743. }
  744. #endif
  745. int serveClientAsync(const SOCKET s_client, const DWORD RpcAssocGroup)
  746. {
  747. #ifndef USE_THREADS // fork() implementation
  748. return ServeClientAsyncFork(s_client, RpcAssocGroup);
  749. #else // threads implementation
  750. PCLDATA thr_CLData = (PCLDATA)vlmcsd_malloc(sizeof(CLDATA));
  751. thr_CLData->socket = s_client;
  752. thr_CLData->RpcAssocGroup = RpcAssocGroup;
  753. #if defined(_WIN32) || defined (__CYGWIN__) // Windows threads
  754. return serveClientAsyncWinThreads(thr_CLData);
  755. #else // Posix Threads
  756. return ServeClientAsyncPosixThreads(thr_CLData);
  757. #endif // Posix Threads
  758. #endif // USE_THREADS
  759. }
  760. #endif // NO_SOCKETS
  761. int runServer()
  762. {
  763. DWORD RpcAssocGroup = rand32();
  764. // If compiled for inetd-only mode just serve the stdin socket
  765. #ifdef NO_SOCKETS
  766. serveClient(STDIN_FILENO, RpcAssocGroup);
  767. return 0;
  768. #else
  769. // In inetd mode just handle the stdin socket
  770. if (InetdMode)
  771. {
  772. serveClient(STDIN_FILENO, RpcAssocGroup);
  773. return 0;
  774. }
  775. for (;;)
  776. {
  777. int error;
  778. SOCKET s_client;
  779. #ifdef SIMPLE_SOCKETS
  780. if ( (s_client = accept(s_server, NULL, NULL)) == INVALID_SOCKET )
  781. #else // Standalone mode fully featured sockets
  782. if ( (s_client = network_accept_any()) == INVALID_SOCKET )
  783. #endif // Standalone mode fully featured sockets
  784. {
  785. error = socket_errno;
  786. if (error == VLMCSD_EINTR || error == VLMCSD_ECONNABORTED) continue;
  787. #ifdef _NTSERVICE
  788. if (ServiceShutdown) return 0;
  789. #endif
  790. #ifndef NO_LOG
  791. logger("Fatal: %s\n",vlmcsd_strerror(error));
  792. #endif
  793. return error;
  794. }
  795. RpcAssocGroup++;
  796. serveClientAsync(s_client, RpcAssocGroup);
  797. }
  798. #endif // NO_SOCKETS
  799. return 0;
  800. }
  801. #endif // USE_MSRPC