1
0

server.c 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850
  1. #include "server.h"
  2. #ifdef _WIN32
  3. /* Msft documentation has this to say: this is required to "initiates use
  4. * of the Winsock DLL by a process." They use technical words like initiates,
  5. * process, and a proper noun. In programming parlance this makes no sense,
  6. * so it boils down to: run this function or else our socket API will not work.
  7. * Bonkers. Get people to include it in their code, and now their code is
  8. * proprietary windows software.
  9. */
  10. int msftVendorLockInCode(WSADATA *w) {
  11. if(WSAStartup(MAKEWORD(2,0), w)) {
  12. fprintf(stderr, "WSAStartup.\n"); return 1;
  13. } else return 0;
  14. }
  15. /* Msft does not implement a close(int socketfd) routine like literally
  16. * every other operating system. Instead they provide closesocket(). Lol.
  17. * Lets ignore the Msft marketing team:
  18. */
  19. int close(int fd) {
  20. return closesocket(fd);
  21. } /* [?] whew, that was hard */
  22. /* Msft does not have a strerror routine and while they copied the Berkley
  23. * Socket API they thought that they could improve on it by renaming and
  24. * removing API constants. Later they introduced a compatibility header
  25. * errno.h but quickly started to erode the compatibility features as they
  26. * added features to their Visual Studio product line so even errno.h is
  27. * useless. Along with redefining the errno global variable and changing
  28. * it to a function (WSAGetLastError()) we still need a way to print human
  29. * readable error messages.
  30. *
  31. * [?] these messages are way too verbose
  32. */
  33. char * strWinsock(int e) {
  34. static char buf[256];
  35. // apparently Msft does not clear buffers
  36. for(int i = sizeof(buf); i--;) buf[i] = '\0';
  37. FormatMessage (
  38. /* flags */ FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
  39. /* lpsource */ NULL,
  40. /* message id */ e,
  41. /* language id */ MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
  42. /* output buffer */ buf,
  43. /* size */ sizeof (buf),
  44. /* va_list args */ NULL
  45. );
  46. if ('\0' == buf[0]) sprintf(buf, "%d-UnknownError", e);
  47. return buf;
  48. }
  49. #endif
  50. // nullify all the "okay" reasons for failure, otherwise signal an abort
  51. int acceptOkay(int e) {
  52. switch(errno) {
  53. #if !defined (_WIN32) && !defined (__linux__)
  54. // linux assigns EAGAIN as EWOULDBLOCK while Msft does not support
  55. case EAGAIN: /* same as EWOULDBLOCK */
  56. #endif
  57. case EWOULDBLOCK:
  58. // in our use case usually a multiplexer timeout
  59. #ifdef PRINT_MULTIPLEXER_TIMEOUT
  60. fprintf(stderr, "probably multiplexer timeout: %s\n", strerror(errno));
  61. #endif
  62. return DONE_FOR_NOW;
  63. #ifndef _WIN32
  64. // Msft winsock does not support these error conditions
  65. case EPROTO: /* just print "client" and errno -. */
  66. case ENOMEM: /* same as ENOBUFS | */
  67. case ENFILE: /* see EMFILE, but system wide v */
  68. #endif
  69. case ECONNABORTED: /* just print "client: errno -. */
  70. case EINTR: /* (these are all okay) | */
  71. case EMFILE: /* per-process limit on open fd | */
  72. case ENOBUFS: /* usually socket buffer limits | */
  73. case EOPNOTSUPP: /* V */
  74. fprintf(stderr, "client: %s\n", strerror(errno));
  75. return 1;
  76. #ifdef __linux__
  77. // linux also suppots firewall rule logging
  78. case EPERM:
  79. fprintf(stderr, "firewall: %s\n", strerror(errno));
  80. return 1;
  81. // in addition linux can support additional logging
  82. case ENOSR:
  83. case ESOCKTNOSUPPORT:
  84. case EPROTONOSUPPORT:
  85. case ETIMEDOUT:
  86. //case ERESTARTSYS:
  87. fprintf(stderr, "additional: %s\n", strerror(errno));
  88. return 1;
  89. #endif
  90. // FATAL error numbers:
  91. case EBADF: /* socket is a bad file descriptor */
  92. case ENOTSOCK: /* socket is not a file descriptor */
  93. case EINVAL: /* not listening, or invalid addrLen */
  94. case EFAULT: /* prevented access violation (addr) */
  95. default:
  96. fprintf(stderr, "FATAL [%d] accept: %s\n", errno, strerror(errno));
  97. return 0;
  98. }
  99. }
  100. int setNonBlocking(int sockfd) {
  101. #ifdef _WIN32
  102. u_long m = 1;
  103. return ioctlsocket(sockfd, FIONBIO, &m);
  104. #else
  105. return fcntl(sockfd, F_SETFL, O_NONBLOCK);
  106. #endif
  107. }
  108. /* [!] allows data loss
  109. * once close is called the OS will immediately delete everything
  110. * in the outgoing buffer, eg: the timeout message will not be
  111. * sent. In addition the client might send a request to this server
  112. * and the OS will most likely drop the packet causing the client
  113. * to hang, waiting on a response
  114. *
  115. * request the OS to send the client tcp stack a request to reset
  116. * connection (causes RST TCP flag to be set) as soon as close is
  117. * called on the socket
  118. */
  119. __attribute__((always_inline)) static
  120. void setLinger(int sockfd) {
  121. struct linger off = { 1, 0 };
  122. #ifdef _WIN32
  123. // Msft changed the type from void pointer to character pointer
  124. #define optval (char *) &off
  125. #else
  126. #define optval &off
  127. #endif
  128. if(0 > setsockopt(sockfd, SOL_SOCKET, SO_LINGER, optval, sizeof(off))) {
  129. fprintf(stderr, "failed to set linger: %s\n", strerror(errno));
  130. }
  131. }
  132. /* Determine if more than allowed number of milliseconds
  133. * have occurred since t
  134. *
  135. * [!] maximum of 2147 milliseconds
  136. */
  137. __attribute__((always_inline)) static
  138. uint32_t msRemaining(struct timespec t, uint32_t allowed) {
  139. struct timespec now;
  140. int32_t seconds, nanoSeconds;
  141. // nanoSecond uses signed 32-bit integer (max: 2,147,483,647)
  142. if(2147 < allowed) {
  143. allowed = 2147;
  144. fprintf(stderr, "[!] remaining max is: %dms\n", 2147);
  145. }
  146. // convert milliseconds allowed to nanoseconds allowed
  147. allowed *= 1.0e6;
  148. // get the current time
  149. clock_gettime(CLOCK_REALTIME, &now);
  150. seconds = now.tv_sec - t.tv_sec;
  151. if(0 > (nanoSeconds = now.tv_nsec - t.tv_nsec)) {
  152. // with negative nanoseconds, there will be at least one second
  153. nanoSeconds += 1.0e9;
  154. if(seconds > 0) seconds--; else { fprintf(stderr, "ouch\n"); return 0; }
  155. }
  156. #ifdef DEBUG_REMAINING
  157. fprintf(stderr, "seconds %d\n", seconds);
  158. fprintf(stderr, "nanoseconds %d\n", nanoSeconds);
  159. #endif
  160. // compare
  161. if(nanoSeconds > allowed) return 0;
  162. /* TODO: calculate the remaining milliseconds
  163. * [!] I am failing to write this code. What I want is to combine seconds
  164. * and nanoseconds but due to the size limitations for integer
  165. * datatypes and the split representation of time_t I am having a
  166. * difficult time.
  167. * [?] What I have so far: I know this function cannot perform calculations
  168. * on time deltas greater than 2 seconds, and the nanosecond resolution
  169. * can cause a fractional second to look like +/- second, so I assume
  170. * anything over 4 seconds is out. I then throw a very large integer
  171. * into the ring to absorb the 1-4 seconds and let the compiler figure
  172. * out the comparison.
  173. */
  174. if(seconds > 4) return 0;
  175. uint64_t humph = nanoSeconds;
  176. if(seconds > 0) while(seconds--) humph += 1.0e9;
  177. if(humph > allowed) return 0;
  178. allowed -= humph;
  179. return allowed / 1.0e6;
  180. }
  181. /* What a hassle. mingw32 deprecated usleep, Msft has a crazy
  182. * interface that you have to spend like ten years filling out
  183. * This is an inaccurate sleep routine.
  184. */
  185. void spookySleep(uint32_t t) {
  186. #ifdef _WIN32
  187. Sleep(t);
  188. #else
  189. usleep(t * 1000);
  190. #endif
  191. }
  192. /* sets up either select or poll and waits up to specified milliseconds for
  193. * operating system to wake up process when an event occurs
  194. */
  195. int socketReady(struct client pool[], int len, uint32_t ms) {
  196. int c, count = 0;
  197. #ifdef MULTIPLEX_USE_SELECT
  198. #define addToSet(x, y) FD_SET(pool[x].fd, &plexfds)
  199. #define isSet(x, y) FD_ISSET(pool[x].fd, &plexfds)
  200. #define waitfor(x) select(x, &plexfds, NULL, NULL, &tv)
  201. fd_set plexfds;
  202. struct timeval tv;
  203. FD_ZERO(&plexfds);
  204. tv.tv_sec = 0;
  205. tv.tv_usec = ms * 1000;
  206. #else
  207. #define addToSet(x, y) \
  208. do { plexfds[y].fd = pool[x].fd; plexfds[y].events = POLLIN; } while(0)
  209. #define isSet(x, y) (plexfds[y].revents & POLLIN)
  210. #define waitfor(x) poll(plexfds, x, ms)
  211. struct pollfd plexfds[POOL_SIZE];
  212. #endif
  213. // restrict len to POOL_SIZE, allows a fixed memory footprint for pollfd
  214. if(POOL_SIZE < len) {
  215. fprintf(stderr, "requested pool size %d limited to %d, ", len, POOL_SIZE);
  216. len = POOL_SIZE;
  217. }
  218. // add all sockets to the file descriptor set
  219. for(int i = 0; i < len; i++) {
  220. // skip pool entries without client socket file descriptors
  221. if(0 > pool[i].fd) continue;
  222. // ignore sockets that the client has already closed
  223. if(CLIENT_IS_CLOSED & pool[i].flags) continue;
  224. addToSet(i, count);
  225. #ifdef PRINT_SOCKET_ADD_TO_SET
  226. if(/* whatever server socket descriptor */ 3 != pool[0].fd)
  227. fprintf(stderr, "add socket descriptor %d to watch list\n", pool[i].fd);
  228. #endif
  229. count++;
  230. }
  231. // go to sleep, wake on OS interrupt (usually timeout or socket activity)
  232. struct timespec t;
  233. clock_gettime(CLOCK_REALTIME, &t);
  234. if(0 == (c = waitfor(count))) {
  235. #ifdef PRINT_NO_SOCKETS_READY
  236. /* try to suppress the server listening socket --
  237. * server socket is usually 3 when stdin, stdout, stderr are left open
  238. * 0 1 2
  239. */
  240. if(/* whatever server socket descriptor */ 3 != pool[0].fd)
  241. fprintf(stderr, "no socket descritprs ready: %d watched, %dms elapsed\n",
  242. count, 1000 - msRemaining(t, 1000));
  243. #endif
  244. return DONE_FOR_NOW;
  245. } else if(-1 == c) {
  246. // print whatever select/poll error case was and return error
  247. fprintf(stderr, "socketReady error: %s\n", strerror(errno));
  248. return /* error */ 0;
  249. } // otherwise...
  250. count = 0;
  251. // set flag for ready sockets
  252. for(int i = 0; i < len; i++) {
  253. // skip pool entries without client socket file descriptors
  254. if(0 > pool[i].fd) continue;
  255. // skip sockets that the client has already closed
  256. if(CLIENT_IS_CLOSED & pool[i].flags) continue;
  257. // either set or unset the READ_READY status bits
  258. if(isSet(i, count)) pool[i].status |= READ_READY;
  259. else pool[i].status &= ~READ_READY;
  260. count++;
  261. }
  262. // return number of clients that have data, as a negative number
  263. #ifdef PRINT_HOW_MANY_SOCKETS_READY
  264. fprintf(stderr, "there are %d socket descriptors ready\n", c);
  265. #endif
  266. return -c;
  267. }
  268. // convert characters in a buffer to only visible printable characters
  269. void convertToPrintable(char * s, uint32_t len) {
  270. char * p = s;
  271. if(len > FIM_BUFFER_LEN) len = FIM_BUFFER_LEN;
  272. for(uint32_t i = 0; i < len; i++) {
  273. if((' ' < *p) && ('z' >= *p)) /* do nothing */ ;
  274. else if('\0' == *p) break;
  275. else *p = '.';
  276. p++;
  277. }
  278. }
  279. /* Demo callback function:
  280. *
  281. * This is an example definition of an example prototype that could be
  282. * passed to the faseItMetal function. Basically it is looking for a
  283. * matching prototype: "char * someFunc(char * s, int len)"
  284. *
  285. * The function returns a pointer, accepts a pointer and a length.
  286. * both pointers are to a character datatype. Users should know that the
  287. * data pointed to will only be read/written up to a limited length (see:
  288. * faceItMetal FIM_BUFFER_LEN).
  289. *
  290. * The len that is passed to the callback is how many bytes the client has
  291. * currently sent to the server.
  292. *
  293. * The limit is set by the callback to tell faceItMetal how many characters
  294. * from the pointer it returns to send to the client. faceItMetal may send
  295. * fewer characters, as mentioned previously (see: faceItMetal FIM_BUFFER_LEN)
  296. *
  297. * Setting this limit to zero means that the callback should be called again
  298. * later with potentially a higher len, assuming the client has sent more
  299. * data. In this case the returned pointer is ignored.
  300. */
  301. char * alwaysGood(char *s, int len, int *limit) {
  302. char *out = "Hola!";
  303. // set how many characters to send to client (hint: see CALLBACK_ERROR_CODES)
  304. *limit = strlen(out);
  305. // print what data the client sent
  306. s[len -1] = '\0';
  307. fprintf(stderr, "alwaysGood: client sent [%s]\n", s);
  308. return out;
  309. }
  310. // see notes from Demo callback function: alwaysGood
  311. char * alwaysBad(char *s, int len, int *limit) {
  312. char *out = "";
  313. // ask to disconnect client with invalid (hint: see CALLBACK_ERROR_CODES)
  314. *limit = INVALID_DATA;
  315. // print what data the client sent
  316. s[len -1] = '\0';
  317. fprintf(stderr, "alwaysBad: client sent [%s]\n", s);
  318. return out;
  319. }
  320. // see notes from Demo callback function: alwaysGood
  321. char * alwaysNotEnough(char *s, int len, int *limit) {
  322. char *out = "";
  323. // ask to disconnect client with invalid (hint: see CALLBACK_ERROR_CODES)
  324. *limit = SEND_MORE;
  325. // print what data the client sent
  326. s[len -1] = '\0';
  327. fprintf(stderr, "alwaysNotEnough: client sent [%s]\n", s);
  328. return out;
  329. }
  330. __attribute__((always_inline)) static
  331. int waitForClients(uint32_t ms, struct client pool[]) {
  332. struct sockaddr_storage address;
  333. struct timespec spec;
  334. socklen_t addrSize;
  335. int c, count = 0;
  336. // store the time before waiting for new clients (ACCEPT_LISTEN_TIME)
  337. clock_gettime(CLOCK_REALTIME, &spec);
  338. /* wait for OS wake-up (okay to ignore invalid events, see: acceptOkay)
  339. *
  340. * [?] rather than check all possible fatal errors in the sleep routine
  341. * we will defer to accept (called in acceptOkay).
  342. * Check for the EAGAIN and EWOULDBLOCK conditions and short on
  343. * either of those (see: DONE_FOR_NOW)
  344. */
  345. if(DONE_FOR_NOW == (c = socketReady(pool, POOL_SIZE, ms))) {
  346. #ifdef USE_CLIENT_POOL
  347. prepayEstimates(pool, POOL_SIZE, spec);
  348. #endif
  349. return DONE_FOR_NOW;
  350. }
  351. // how many clients can be added to the pool
  352. for(int i = POOL_SIZE; i--;) if(-1 == pool[i].fd) count++;
  353. // accept any inbound connections, make a socket - short on error
  354. if(READ_READY & pool[0].status) while(count) {
  355. // reset the address length parameter (accept may modify it)
  356. addrSize = sizeof(address);
  357. // pull the next connection request from the listening socket queue
  358. if(0 > (c = accept(pool[0].fd, (struct sockaddr *) &address, &addrSize))) {
  359. // normal case for break is when errno is EWOULDBLOCK or EAGAIN
  360. if(DONE_FOR_NOW == (c = acceptOkay(errno))) break;
  361. // abort if there is a problem with the listening socket
  362. if(c) {
  363. fprintf(stderr, "unusual accept, skipping\n");
  364. continue;
  365. } else return /* fatal */ 0;
  366. } //else
  367. // reconfigure the client for non-blocking IO mode
  368. if(0 > setNonBlocking(c)) {
  369. fprintf(stderr, "problem setting mode: %s\n", strerror(errno));
  370. close(c); continue;
  371. }
  372. // add client to pool (record their file descriptor and connection time
  373. for(int i = /* skip listen socket */ 1; i < POOL_SIZE; i++) {
  374. // find an unused space in the client pool
  375. if(-1 < pool[i].fd) continue;
  376. #ifdef PRINT_CLIENT_ACCEPTED
  377. fprintf(stderr, "new client\n");
  378. #endif
  379. pool[i].fd = c;
  380. pool[i].address = address;
  381. pool[i].addrSize = addrSize;
  382. pool[i].t = spec;
  383. pool[i].status = 0;
  384. pool[i].flags = 0;
  385. pool[i].ms = PER_CLIENT_TIMEOUT_MS;
  386. // reset buffer counter
  387. pool[i].count = 0;
  388. // clear out a buffer to store user data
  389. for(uint32_t j = FIM_BUFFER_LEN; j--;) pool[i].buf[j] = '\0';
  390. // decrease the amount of space in the pool
  391. count--;
  392. break;
  393. }
  394. }
  395. // remove the READ_READY flag
  396. pool[0].status &= ~READ_READY;
  397. #ifdef USE_CLIENT_POOL
  398. prepayEstimates(pool, POOL_SIZE, spec);
  399. #endif
  400. return /* okay */ 1;
  401. }
  402. /* client socket has some pending data that has not been retrieved yet
  403. * collect it from the OS' buffers and then test if the data is complete enough
  404. * to send a response to the client.
  405. *
  406. * returns either a negative code or how many bytes were sent to the client
  407. *
  408. *
  409. */
  410. __attribute__((always_inline)) static
  411. int replyOnValid(struct client *c, char * (*f)(char *s, int len, int *limit)) {
  412. int d, e;
  413. char *res, response[FIM_BUFFER_LEN];
  414. // canned messages to send to clients
  415. static char * invalid = INVALID_TEXT;
  416. static char * error = SERVER_ERROR_TEXT;
  417. // skip unused spaces in pool, and clients without data to be processed
  418. if((0 > c->fd) || (0 == (READ_READY & c->status))) return /* skip */ -3;
  419. // also skip pooled clients that have closing type flags
  420. if(CLIENT_CLOSING & c->flags) return /* skip */ -3;
  421. do { // fill buffer, then flush (use response as overflow)
  422. if(0 < (e = FIM_BUFFER_LEN - c->count)) {
  423. if(0 < (d = recv(c->fd, c->buf + c->count, e, 0))) c->count += d;
  424. } else d = recv(c->fd, response, FIM_BUFFER_LEN, 0);
  425. } while(0 < d);
  426. // when read returns zero, client has already disconnected
  427. if(0 == d) {
  428. #ifdef PRINT_CLIENT_DISCONNECT
  429. fprintf(stderr, "client has disconnected\n");
  430. #endif
  431. c->flags |= CLIENT_IS_CLOSED;
  432. return /* it is okay */ -1;
  433. } else if (0 > d) {
  434. /* usually on the first wake-up but sometimes a bit later, we will
  435. * eventually consume everything a client wants to send and the client
  436. * will not say anything until we respond, when this happens the
  437. * recv function will continuously set errno to EWOULDBLOCK
  438. */
  439. //fprintf(stderr, "recv(%d): %s\n", errno, strerror(errno));
  440. }
  441. // skip callback if the server already decided to close the connection
  442. if(SERVER_WANTS_CLOSE & c->flags) return /* it is okay */ -1;
  443. // swap last character in buffer with a null terminator for safety
  444. c->buf[FIM_BUFFER_LEN - 1] = '\0';
  445. #ifdef PRINT_CLIENT_DATA
  446. fprintf(stderr, "client data: %s\n", c->buf);
  447. #endif
  448. { e = SERVER_ERROR;
  449. res = f(c->buf, c->count > FIM_BUFFER_LEN ?FIM_BUFFER_LEN :c->count, &e);
  450. }
  451. // if the limit is negative treat like a CALLBACK_ERROR_CODE
  452. if(0 > e) switch(e) {
  453. case SEND_MORE: /* partial request */
  454. // terminate if client filled our buffer unusable stuff
  455. if(FIM_BUFFER_LEN == c->count) {
  456. fprintf(stderr, "thanks for all the fish\n");
  457. break;
  458. } else return /* partial request */ -2;
  459. // these error codes cause client disconnect (use break)
  460. case INVALID_DATA:
  461. fprintf(stderr, "callback: invalid data\n");
  462. sendResponse(c, invalid, strlen(invalid), INVALID_MSG);
  463. break;
  464. case DROP_CLIENT:
  465. fprintf(stderr, "callback: drop client\n");
  466. c->flags = CLOSE_IMMEDIATELY;
  467. setLinger(c->fd);
  468. break;
  469. case SERVER_ERROR:
  470. fprintf(stderr, "callback: server error\n");
  471. sendResponse(c, error, strlen(error), SERVER_ERROR_MSG);
  472. break;
  473. default:
  474. fprintf(stderr, "unknown CALLBACK_ERROR_CODE [%d]\n", e);
  475. } if(0 > e) { c->flags |= SERVER_WANTS_CLOSE; return /* error */ -1; }
  476. // set the limit for how much data should be copied
  477. d = e < FIM_BUFFER_LEN ?e :FIM_BUFFER_LEN;
  478. // copy data into the response buffer
  479. for(uint32_t i = 0; i < d; i++) response[i] = *res++;
  480. // client has sent a valid request, send them the response
  481. if(d > (e = sendResponse(c, response, d, RESPONSE_MSG))) {
  482. if(0 > e); else fprintf(stderr, "truncated: %d of %d\n", e, d);
  483. }
  484. // finished with this client (server wants to close their socket)
  485. c->flags |= SERVER_WANTS_CLOSE;
  486. return d;
  487. }
  488. /* Note about send:
  489. * when writing to a pipe that the remote end has broken, we receive a
  490. * -1 from send and errno is set to EPIPE, but before that happens the
  491. * OS will send the application the SIGPIPE signal. Handle sigpipe, record
  492. * the send return value (on success number of bytes sent, otherwise -1
  493. * and errno is set)
  494. */
  495. int sendResponse(struct client *c, char *buf, uint32_t len, sendReason reason) {
  496. int d;
  497. if(WRITE_CLOSED & c->status) {
  498. fprintf(stderr, "cannot send, we already closed our end\n");
  499. return -1;
  500. }
  501. if(-1 == (d = send(c->fd, buf, len, 0))) {
  502. #ifdef _WIN32
  503. /* Msft winsock api does not implement anything to handle a broken
  504. * pipe, instead they return either zero for normal disconnect and
  505. * -1 for error. So that is fun.
  506. */
  507. if(1) {
  508. #else
  509. // handle general send errors
  510. if(EPIPE != errno) {
  511. #endif
  512. fprintf(stderr, "send error: %s\n", strerror(errno));
  513. c->flags |= CLIENT_IS_CLOSED;
  514. return d;
  515. }
  516. // on broken pipe, the remote end has already closed
  517. c->flags |= CLIENT_IS_CLOSED;
  518. #ifdef PRINT_CLIENT_DISCONNECT
  519. switch(reason) {
  520. case TIME_OUT_MSG:
  521. case INVALID_MSG:
  522. case SERVER_ERROR_MSG:
  523. fprintf(stderr, "client has disconnected before send complete\n");
  524. break;
  525. case RESPONSE_MSG:
  526. fprintf(stderr, "client has disconnected before response sent\n");
  527. break;
  528. default: ;
  529. }
  530. #endif
  531. return d;
  532. }
  533. // prevent further transmission, sends final packet (FIN TCP flag)
  534. if(0 == (WRITE_CLOSED & c->status)) {
  535. c->status |= WRITE_CLOSED;
  536. shutdown(c->fd, SHUT_WR);
  537. }
  538. return d;
  539. }
  540. __attribute__((always_inline)) static
  541. void sendTimeout(struct client *c) {
  542. // canned messages to send to clients
  543. static char * timeout = TIMEOUT_TEXT;
  544. fprintf(stderr, "client timeout\n");
  545. #ifndef USE_CLIENT_POOL
  546. /* when the write side of the pipe is closed but client has not, maybe
  547. * we can nudge the socket into closing
  548. */
  549. char buf[512]; memset(buf, 0, sizeof(buf));
  550. if(-1 == send(c->fd, buf, sizeof(buf), 0)) {
  551. if(EPIPE == errno) {
  552. fprintf(stderr, "closed using send\n");
  553. c->flags |= CLIENT_IS_CLOSED;
  554. return;
  555. }
  556. }
  557. #endif
  558. sendResponse(c, timeout, strlen(timeout), TIME_OUT_MSG);
  559. /* [!] allow data loss
  560. * once close is called the OS will immediately delete everything
  561. * in the outgoing buffer, eg: the timeout message will not be
  562. * sent. In addition the client might send a request to this server
  563. * and the OS will most likely drop the packet causing the client
  564. * to hang, waiting on a response
  565. *
  566. * request the OS to send the client tcp stack a request to reset
  567. * connection (causes RST TCP flag to be set) as soon as close is
  568. * called on the socket
  569. */
  570. setLinger(c->fd);
  571. c->flags |= SERVER_WANTS_CLOSE;
  572. }
  573. #ifdef USE_CLIENT_POOL
  574. __attribute__((always_inline)) static
  575. void checkTimeouts(struct client pool[], int len) {
  576. uint32_t ms;
  577. for(int i = len; i--;) {
  578. // do not check the server socket
  579. if(0 == i) continue;
  580. // skip unused pooled spaces, or already closing clients
  581. if((0 > pool[i].fd) || (CLIENT_CLOSING & pool[i].flags)) continue;
  582. // also skip those clients that still have remaining milliseconds
  583. if(0 < pool[i].ms) continue;
  584. // run calculations on this client to determine if really timed out
  585. if(0 < (ms = msRemaining(pool[i].t, PER_CLIENT_TIMEOUT_MS / 2))) {
  586. // restore clients actual remaining milliseconds
  587. pool[i].ms = ms;
  588. continue;
  589. }
  590. /* at this point the client has no more time left, maybe they sent some
  591. * data in the last possible instant and they may have a legitimate
  592. * request, or the server is running slow and we have not sent the
  593. * client a final packet, either way the timeout rule says that we are
  594. * done communicating with this client, cut them off completely
  595. *
  596. * [?] we should have sent the client a timeout and a final packet,
  597. * log when we have not done so
  598. */
  599. if(SERVER_WANTS_CLOSE & pool[i].flags) {
  600. if(0 == (WRITE_CLOSED & pool[i].status))
  601. fprintf(stderr, "never sent a packet with FIN flag\n");
  602. setLinger(pool[i].fd);
  603. pool[i].flags |= CLOSE_IMMEDIATELY;
  604. continue;
  605. }
  606. // okay, send this client a timeout message
  607. sendTimeout(&pool[i]);
  608. }
  609. }
  610. /* at various times it may be easy to make a guess about time passing, for
  611. * example, after making a sleep based system call and having no interruption
  612. * occur, the requested sleep time will have passed.
  613. * It is not really important to get this right, it is just an easy way
  614. * to sometimes save some CPU time.
  615. *
  616. * [?] The ACCEPT_LISTEN_TIME is used to for new clients avoiding the time the
  617. * sever spent waiting on old clients while listening
  618. */
  619. __attribute__((always_inline)) static
  620. void prepayEstimates(struct client p[], uint32_t len, struct timespec t) {
  621. // estimate remaining milliseconds elapsed to use for client timeouts
  622. uint32_t ms = PER_CLIENT_TIMEOUT_MS - msRemaining(t, PER_CLIENT_TIMEOUT_MS);
  623. for(int i = len; i--;) {
  624. // either remove milliseconds or do so next time
  625. if(ACCEPT_LISTEN_TIME & p[i].status) {
  626. p[i].ms = p[i].ms > ms ?(p[i].ms - ms) :0;
  627. } else p[i].status |= ACCEPT_LISTEN_TIME;
  628. }
  629. }
  630. #endif
  631. /* Three things can happen:
  632. * 1. just the transmit side of the full-duplex socket can be closed, in
  633. * which case the client may still send data and we will be unable to
  634. * respond, the socket will not be closed although client will be sent a
  635. * request to close
  636. * 2. we may close a socket, after the client says it is okay to do so - this
  637. * is the normal case, where a client has closed the receive side of the
  638. * full-duplex socket and we are unable to send anything else to the client
  639. * 3. for some reason we just want to drop a connection without notifying
  640. * the client. This will cause TIME_WAIT, but might be improved if the
  641. * Operating System is notified in advance with the SO_LINGER option
  642. *
  643. * Technically the client should be closing the connection so the nice /
  644. * correct thing to do is to send our goodbye intentions by setting the FIN
  645. * TCP flag in either the last or an empty packet and transmitting this. Upon
  646. * receiving the FIN flagged packet the client will send back a their close
  647. * and then we can close. But we do not really want to wait here for that,
  648. * instead we are just sending the FIN and then coming back later. Because TCP
  649. * guarantees packet data delivery the socket API would need to guarantee that
  650. * we got whatever the client sent, even though, at this point they may not
  651. * have sent it. We have to come back later and see if the client is finished
  652. * before calling close on the client socket file descriptor.
  653. *
  654. * Unless, it is a close immediately situation, so not TCP, we are just going
  655. * to drop the socket and call close on it. If there is still a client
  656. * connected it would hang / freeze.
  657. *
  658. * returns the number of socket file descriptors released to OS (one on
  659. * close immediately/client is already closed, zero otherwise)
  660. */
  661. int goodbyes(struct client *c) {
  662. // skip unused spaces in pool
  663. if(0 > c->fd) return 0;
  664. // can only say goodbye to a closed client
  665. if(0 == (CLIENT_CLOSING & c->flags)) return 0;
  666. // print what might have been sent to client, convert non-visible characters
  667. if(c->count) {
  668. // convert the users sent buffer into only visible characters and print
  669. convertToPrintable(c->buf, c->count);
  670. c->buf[FIM_BUFFER_LEN - 1] = '\0';
  671. fprintf(stderr, "client sent:\n%s\n", c->buf);
  672. }
  673. /* close without waiting for client to close first will cause TIME_WAIT
  674. * sockets. Usually the OS will reap these in several minutes, also
  675. * clients that are still connected will hang. So, probably better to
  676. * not do this all the time, but we still need to do this on occasion
  677. * due to the fact that we are talking to another computer that might
  678. * need to perform a BSOD or some other slightly more important crash
  679. * right now
  680. */
  681. char host[NI_MAXHOST], service[NI_MAXSERV];
  682. int d;
  683. // when close is performed without notifying client, print warning
  684. if(CLOSE_IMMEDIATELY & c->flags) fprintf(stderr, "[!] immediate ");
  685. if(0 == (d = getnameinfo(
  686. (struct sockaddr *) &c->address,
  687. c->addrSize,
  688. host, NI_MAXHOST,
  689. service, NI_MAXSERV, NI_NUMERICSERV))) {
  690. fprintf(stderr, "close: %s\n\n", host);
  691. } else {
  692. fprintf(stderr, "getnameinfo error: %s\n", gai_strerror(d));
  693. fprintf(stderr, "close\n\n");
  694. }
  695. close(c->fd);
  696. // remove the socket file descriptor from the pool
  697. c->fd = -1;
  698. return 1;
  699. }
  700. /* when handling a single client and socketReady returns zero, indicating that
  701. * select/poll sleep returned -1, and errno was set. I guess it depends on
  702. * what that error is, but it seems like we can just drop the client and move
  703. * on. generate a log message at a minimum for now.
  704. *
  705. */
  706. __attribute__((always_inline)) static int wakeupError(int e, struct client * c) {
  707. if(e) return /* false */ 0;
  708. fprintf(stderr, "closing client socket due to socketReady fail.\n");
  709. c->flags |= CLOSE_IMMEDIATELY;
  710. return /* true */ 1;
  711. }
  712. /* sleep some number of milliseconds, but wake-up when a client connects
  713. * clients are given up to 10 milliseconds to send data
  714. *
  715. * caller will pass a function that validates a string and returns a pointer
  716. * to a buffer to send back to the client as a response
  717. * a buffer containing a leading null is used to determine if the client
  718. * has sent a partial request. In this case nothing will be sent to the client,
  719. * the clients request will be later resent, in full, to the validation function
  720. *
  721. * the buffer will have a maximum length of FIM_BUFFER_LEN
  722. */
  723. #ifdef USE_CLIENT_POOL
  724. int faceItMetal(uint32_t ms, char * (*f)(char *s, int len, int *limit),
  725. struct client pool[]) {
  726. int c;
  727. struct timespec spec;
  728. // wait for client connections using a timeout (fatal on failure)
  729. if(0 == waitForClients(ms, pool)) return 0;
  730. // store the time before waiting on client data
  731. clock_gettime(CLOCK_REALTIME, &spec);
  732. // latest wake up is half of PER_CLIENT_TIMEOUT_MS
  733. ms = PER_CLIENT_TIMEOUT_MS / 2;
  734. // on wake up retrieve any pending data for each client, if possible reply
  735. if(DONE_FOR_NOW == (c = socketReady(pool, POOL_SIZE, ms))) {
  736. } else if(c) {
  737. // if there was a new client, add them
  738. if((READ_READY & pool[0].status) && (0 == waitForClients(0, pool))) return 0;
  739. for(int i = POOL_SIZE; i--;) replyOnValid(&pool[i], f);
  740. }
  741. // estimate the remaining milliseconds before timeout for all clients
  742. prepayEstimates(pool, POOL_SIZE, spec);
  743. // send timeout messages to all timed out clients
  744. checkTimeouts(pool, POOL_SIZE);
  745. // send farewells to closing clients (skip the listening socket)
  746. for(int i = POOL_SIZE; i--;) { if(0 == i) continue; goodbyes(&pool[i]); }
  747. return /* okay */ 1;
  748. }
  749. #else
  750. int faceItMetal(int sock, uint32_t ms, char * (*f)(char *s, int len, int *limit)) {
  751. // when not using pooling, POOL_SIZE is 2
  752. struct client pool[POOL_SIZE];
  753. int c;
  754. // [?] even though we are not using pooling, setup pool
  755. pool[0].fd = sock; pool[1].fd = -1;
  756. // wait for client connections using a timeout (fatal on failure)
  757. if(0 == waitForClients(ms, pool)) return 0;
  758. if(-1 == pool[1].fd) return /* timeout */ 1;
  759. if((0 == handleClient(pool, f)) && (0 == (CLIENT_CLOSING & pool[1].flags))) {
  760. sendTimeout(&pool[1]);
  761. }
  762. // say goodbye to client, finished early if socket is released
  763. if(goodbyes(&pool[1])) return /* okay */ 1;
  764. // client was told to close, it has the remaining time to do so
  765. handleClient(pool, f);
  766. // set a closing flag if there is none, then initiate irrefutable farewell
  767. if(0 == (CLIENT_CLOSING & pool[1].flags)) pool[1].flags |= CLOSE_IMMEDIATELY;
  768. goodbyes(&pool[1]);
  769. return /* okay */ 1;
  770. }
  771. int handleClient(struct client p[], char * (*f)(char *s, int len, int *limit)) {
  772. struct timespec spec;
  773. uint32_t ms;
  774. int c;
  775. clock_gettime(CLOCK_REALTIME, &spec);
  776. while(0 < (ms = msRemaining(spec, PER_CLIENT_TIMEOUT_MS / 2))) {
  777. // [?] unsure - browsers may not always close their socket in time
  778. if(DONE_FOR_NOW == (c = socketReady(&p[1], 1, ms))) continue;
  779. if(wakeupError(c, &p[1])) break;
  780. // retrieve any pending data for the client, if possible reply
  781. replyOnValid(&p[1], f);
  782. // check for an early exit, client should close their connection
  783. if(CLIENT_CLOSING & p[1].flags) break;
  784. }
  785. return ms;
  786. }
  787. #endif
  788. #ifndef _WIN32
  789. /* when the application receives SIGPIPE, the OS was probably was the source
  790. * of the signal. It is telling us that whatever send that is currently being
  791. * called will fail with an EPIPE due to the remote end of a connected socket
  792. * being closed.
  793. *
  794. * This is fine, we cannot control the other computer or application, but not
  795. * handling the signal will cause the OS to close our application if the signal
  796. * is not handled. Install this signal handler on setup to make sure that
  797. * the signal is handled.
  798. *
  799. * [?] Normally we would just set the MSG_NOSIGNAL flag but Msft Winsock API
  800. * does not support this flag. We could just set the flag on Unix based
  801. * OSes.
  802. */
  803. void handle_sigpipe(int s) {
  804. fprintf(stderr, "recieved SIGPIPE: probably remote end broke connection\n");
  805. }
  806. #endif
  807. /* The main reason for this code is to hide some Msft proprietary code
  808. * but obviously if you want to run something at the "end" of the program
  809. * you can do that here. Initially non-Microsoft OSes will just return zero
  810. * while Msft wanders around aimlessly.
  811. *
  812. * [!] The name of this function is pretty important, it was picked as to not
  813. * represent anything related to exiting, goodbye, or leaving. It does not
  814. * have these functionality. For most operating systems it just returns
  815. * zero. For Msft it is used when the Winsock interface is no longer
  816. * needed (see: WSACleanup)
  817. */
  818. int softCuteBunnies(int c) {
  819. #ifdef _WIN32
  820. // do the shutdown dance for Msft
  821. WSACleanup();
  822. #endif
  823. return c;
  824. }