1 /*
2 * Copyright (c) 2011, 2012, 2013
3 * Inferno Nettverk A/S, Norway. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. The above copyright notice, this list of conditions and the following
9 * disclaimer must appear in all copies of the software, derivative works
10 * or modified versions, and any portions thereof, aswell as in all
11 * supporting documentation.
12 * 2. All advertising materials mentioning features or use of this software
13 * must display the following acknowledgement:
14 * This product includes software developed by
15 * Inferno Nettverk A/S, Norway.
16 * 3. The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 *
30 * Inferno Nettverk A/S requests users of this software to return to
31 *
32 * Software Distribution Coordinator or sdc@inet.no
33 * Inferno Nettverk A/S
34 * Oslo Research Park
35 * Gaustadall�en 21
36 * NO-0349 Oslo
37 * Norway
38 *
39 * any improvements or extensions that they make and grant Inferno Nettverk A/S
40 * the rights to redistribute these changes.
41 *
42 */
43
44 #include "common.h"
45
46 static const char rcsid[] =
47 "$Id: statistics.c,v 1.33 2013/10/27 15:24:43 karls Exp $";
48
49
50 int
sockd_check_ipclatency(description,tsent,treceived,tnow)51 sockd_check_ipclatency(description, tsent, treceived, tnow)
52 const char *description;
53 const struct timeval *tsent;
54 const struct timeval *treceived;
55 const struct timeval *tnow;
56 {
57 #if DIAGNOSTIC
58 const char *function = "sockd_check_ipclatency()";
59 const size_t samplesneeded = 1000,
60 minoccurences = 10;
61 const time_t tseconds_between_warnings = 60;
62 static struct timeval tmaxdelay, tmaxdelay_so_far;
63 static size_t samplec;
64 struct timeval tdiff;
65
66 timersub(treceived, tsent, &tdiff);
67
68 if (tdiff.tv_sec < 0) {
69 swarnx("%s: strange ... received ts (%ld.%06ld) is earlier than "
70 "sent ts (%ld.%06ld) . Did the clock step backwards?",
71 function,
72 (long)treceived->tv_sec,
73 (long)treceived->tv_usec,
74 (long)tsent->tv_sec,
75 (long)tsent->tv_usec);
76
77 return 0;
78 }
79 else
80 slog(LOG_DEBUG, "%s: %s: used %luus to receive object",
81 function, description, tv2us(&tdiff));
82
83 if (timerisset(&tmaxdelay)) {
84 if (timercmp(&tdiff, &tmaxdelay, >)) {
85 static time_t tlastwarn, tlongest;
86 static size_t overloadc;
87
88 ++overloadc;
89
90 if ((time_t)tv2us(&tdiff) > tlongest)
91 tlongest = (time_t)tv2us(&tdiff);
92
93 if (socks_difftime(tnow->tv_sec, tlastwarn)
94 >= tseconds_between_warnings) {
95 if (overloadc >= minoccurences)
96 slog(LOG_NOTICE,
97 "server overload condition detected %lu time%s regarding "
98 "%s. Used up to %ldus to receive new client objects "
99 "during the last %lds, but expected maximum was "
100 "calibrated to %luus",
101 (unsigned long)overloadc,
102 (unsigned long)overloadc == 1 ? "" : "s",
103 description,
104 (long)tlongest,
105 (long)socks_difftime(tnow->tv_sec, tlastwarn),
106 tv2us(&tmaxdelay));
107
108 tlastwarn = tnow->tv_sec;
109 overloadc = 0;
110 tlongest = 0;
111 }
112
113 return 1;
114 }
115
116 return 0;
117 }
118
119 if (timercmp(&tdiff, &tmaxdelay_so_far, >))
120 tmaxdelay_so_far = tdiff;
121
122 if (samplec == samplesneeded) {
123 tmaxdelay = tmaxdelay_so_far;
124
125 slog(DEBUG ? LOG_INFO : LOG_DEBUG,
126 "%s: max IPC delay for this %s process calibrated to be %ld.%06lds",
127 function,
128 childtype2string(sockscf.state.type),
129 (long)tmaxdelay.tv_sec,
130 (long)tmaxdelay.tv_usec);
131 }
132 else
133 ++samplec;
134 #endif /* DIAGNOSTIC */
135
136 return 0;
137 }
138