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