netwrite.c (2840B)
1 /************************************************************************* 2 * This file is part of Crosroads 1.23, a load balancer and fail over 3 * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. 4 * Visit http://crossroads.e-tunity.com for information. 5 *************************************************************************/ 6 #include "crossroads.h" 7 8 /* Define DUMPFILE if you want Crossroads to dump the contents of what's 9 * written to the client or to the server to 10 * /tmp/crossroads-sentto{client,server}.dump. This is of course for deep 11 * mode debugging only. 12 */ 13 // #define DUMPFILE 14 15 int net_write (int sock, unsigned char const *buf, unsigned buflen, 16 int is_client) { 17 int ret, nfd; 18 struct timeval tv, tv1, tv2, *tvp; 19 double microsec; 20 fd_set fdset, exset; 21 22 #ifdef DUMPFILE 23 FILE *f; 24 char *fname; 25 26 if (is_client) 27 fname = "/tmp/crossroads-senttobackend.dump"; 28 else 29 fname = "/tmp/crossroads-senttoclient.dump"; 30 if (! (f = fopen (fname, "a"))) 31 f = fopen (fname, "w"); 32 if (f) { 33 fprintf (f, "[0x%x %d bytes] ", buflen, buflen); 34 fwrite (buf, 1, buflen, f); 35 fclose (f); 36 } 37 #endif 38 39 /* Start timer */ 40 gettimeofday (&tv1, 0); 41 42 /* Prepare the write. */ 43 FD_ZERO (&fdset); 44 FD_ZERO (&exset); 45 FD_SET (sock, &fdset); 46 FD_SET (sock, &exset); 47 if (activeservice->connectiontimeout) { 48 tv.tv_sec = activeservice->connectiontimeout; 49 tv.tv_usec = 0; 50 tvp = &tv; 51 } else 52 tvp = 0; 53 if ( (nfd = select (FD_SETSIZE, 0, &fdset, &exset, tvp)) < 1) { 54 if (!nfd) 55 warning ("Service %s: Timout while writing %s on socket %d", 56 activeservice->name, 57 is_client ? "client" : "server", sock); 58 else 59 warning ("Service %s: Failed to wait for network of %s " 60 "on socket %d", 61 activeservice->name, 62 is_client ? "client" : "server", sock); 63 64 decr_client_count(); 65 log_activity_end(); 66 if (!is_client) 67 mark_activity (0, 0, st_unavailable); 68 exit (0); 69 } 70 71 if (FD_ISSET (sock, &exset)) { 72 decr_client_count(); 73 log_activity_end(); 74 error ("Service %s: exception on %s network", 75 is_client ? "client" : "server"); 76 } 77 78 /* We can write! */ 79 ret = write (sock, buf, buflen); 80 81 /* Check for finished / errors */ 82 if (ret < 1) { 83 if (ret < 0 && !is_client) 84 mark_activity (0, 0, st_unavailable); 85 decr_client_count(); 86 log_activity_end (); 87 if (ret < 0) 88 error ("Service %s: write error when copying to %s", 89 activeservice->name, is_client ? "client" : "server"); 90 } 91 92 /* Update activity. */ 93 gettimeofday (&tv2, 0); 94 microsec = ( (tv2.tv_sec * 1000000 + tv2.tv_usec) - 95 (tv1.tv_sec * 1000000 + tv1.tv_usec) ); 96 mark_activity (ret, microsec / 1000000, st_intermediate); 97 98 /* Signal caller how many bytes were written. */ 99 return (ret); 100 } 101 102