netread.c (2488B)
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 unsigned net_read (int sock, unsigned max, unsigned char *buf, int is_client) { 9 fd_set readset, exset; 10 struct timeval tv, *tvp, tv1, tv2; 11 int nfd; 12 unsigned nread; 13 CopyDirection dir; 14 double microsec; 15 char *desc; 16 17 desc = is_client ? "client" : "server"; 18 dir = is_client ? dir_client_to_server : dir_server_to_client; 19 20 msg ("Service %s: fetching atmost %u bytes from %s", 21 activeservice->name, max, desc); 22 23 /* Prepare select() sets */ 24 FD_ZERO (&readset); 25 FD_ZERO (&exset); 26 FD_SET (sock, &readset); 27 FD_SET (sock, &exset); 28 29 /* Prepare timout state */ 30 if (activeservice->connectiontimeout) { 31 tv.tv_sec = activeservice->connectiontimeout; 32 tv.tv_usec = 0; 33 tvp = &tv; 34 } else 35 tvp = 0; 36 37 /* Wait for the socket to become readable */ 38 gettimeofday (&tv1, 0); 39 nfd = select (FD_SETSIZE, &readset, 0, &exset, tvp); 40 if (nfd < 1) { 41 decr_client_count(); 42 log_activity_end(); 43 mark_activity (0, 0, is_client ? st_available : st_unavailable); 44 error ("Service %s: read from %s timed out", 45 activeservice->name, desc); 46 } 47 48 /* Check for exceptions. */ 49 if (FD_ISSET (sock, &exset)) { 50 decr_client_count(); 51 log_activity_end(); 52 mark_activity (0, 0, is_client ? st_available : st_unavailable); 53 error ("Service %s: %s exception", desc, activeservice->name); 54 } 55 56 /* Do the read. */ 57 nread = read (sock, buf, max - 1); 58 if (nread < 1) { 59 decr_client_count(); 60 log_activity_end(); 61 if (nread < 0) { 62 mark_activity (0, 0, is_client ? st_available : st_unavailable); 63 error ("Service %s: read error when getting data from %s", 64 activeservice->name, desc); 65 } else { 66 msg ("Service %s: %s signals end of data", 67 activeservice->name, desc); 68 exit (0); 69 } 70 } 71 72 /* Update thruput / traffic logs. */ 73 trafficlog (buf, nread, dir); 74 thruputlog (buf, nread, dir); 75 gettimeofday (&tv2, 0); 76 microsec = ( (tv2.tv_sec * 1000000 + tv2.tv_usec) - 77 (tv1.tv_sec * 1000000 + tv1.tv_usec) ); 78 79 mark_activity (nread, microsec / 1000000, st_intermediate); 80 81 return (nread); 82 }