xref: /freebsd/tests/sys/kern/sonewconn_overflow.py (revision 631d525dc187dd55c034b093c0d1810c513b4de2)
1*631d525dSJonathan T. Looney#!/usr/bin/env python
2*631d525dSJonathan T. Looney#-
3*631d525dSJonathan T. Looney# SPDX-License-Identifier: BSD-2-Clause
4*631d525dSJonathan T. Looney#
5*631d525dSJonathan T. Looney# Copyright (c) 2020 Netflix, Inc.
6*631d525dSJonathan T. Looney#
7*631d525dSJonathan T. Looney# Redistribution and use in source and binary forms, with or without
8*631d525dSJonathan T. Looney# modification, are permitted provided that the following conditions
9*631d525dSJonathan T. Looney# are met:
10*631d525dSJonathan T. Looney# 1. Redistributions of source code must retain the above copyright
11*631d525dSJonathan T. Looney#    notice, this list of conditions and the following disclaimer.
12*631d525dSJonathan T. Looney# 2. Redistributions in binary form must reproduce the above copyright
13*631d525dSJonathan T. Looney#    notice, this list of conditions and the following disclaimer in the
14*631d525dSJonathan T. Looney#    documentation and/or other materials provided with the distribution.
15*631d525dSJonathan T. Looney#
16*631d525dSJonathan T. Looney# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17*631d525dSJonathan T. Looney# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18*631d525dSJonathan T. Looney# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19*631d525dSJonathan T. Looney# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20*631d525dSJonathan T. Looney# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21*631d525dSJonathan T. Looney# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22*631d525dSJonathan T. Looney# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23*631d525dSJonathan T. Looney# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24*631d525dSJonathan T. Looney# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25*631d525dSJonathan T. Looney# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26*631d525dSJonathan T. Looney# SUCH DAMAGE.
27*631d525dSJonathan T. Looney#
28*631d525dSJonathan T. Looney# $FreeBSD$
29*631d525dSJonathan T. Looney#
30*631d525dSJonathan T. Looney
31*631d525dSJonathan T. Looneyimport socket
32*631d525dSJonathan T. Looneyimport os
33*631d525dSJonathan T. Looneyimport sys
34*631d525dSJonathan T. Looneyfrom subprocess import check_output
35*631d525dSJonathan T. Looneyfrom time import sleep
36*631d525dSJonathan T. Looney
37*631d525dSJonathan T. LooneyV4HOST = '127.0.0.1'
38*631d525dSJonathan T. LooneyV6HOST = '::1'
39*631d525dSJonathan T. LooneyTCPPORT = 65432
40*631d525dSJonathan T. LooneyUNIXSOCK = '/tmp/testsock'
41*631d525dSJonathan T. LooneyTYPE = socket.SOCK_STREAM
42*631d525dSJonathan T. Looney
43*631d525dSJonathan T. Looneyclass GenericTest(object):
44*631d525dSJonathan T. Looney    def __init__(self):
45*631d525dSJonathan T. Looney        raise NotImplementedError("Subclass must override the __init__ method")
46*631d525dSJonathan T. Looney    def setup(self, af, addr):
47*631d525dSJonathan T. Looney        self.sockets = []
48*631d525dSJonathan T. Looney        self.ls = None
49*631d525dSJonathan T. Looney        self.ls = socket.socket(af, TYPE)
50*631d525dSJonathan T. Looney        self.ls.bind(addr)
51*631d525dSJonathan T. Looney        self.ls.listen(2)
52*631d525dSJonathan T. Looney        self.af = af
53*631d525dSJonathan T. Looney        self.addr = addr
54*631d525dSJonathan T. Looney    def doTest(self, cnt):
55*631d525dSJonathan T. Looney        rv = 0
56*631d525dSJonathan T. Looney        for i in range(0, cnt):
57*631d525dSJonathan T. Looney            try:
58*631d525dSJonathan T. Looney                s = socket.socket(self.af, TYPE)
59*631d525dSJonathan T. Looney                s.connect(self.addr)
60*631d525dSJonathan T. Looney            except:
61*631d525dSJonathan T. Looney                continue
62*631d525dSJonathan T. Looney            self.sockets.append(s)
63*631d525dSJonathan T. Looney            rv += 1
64*631d525dSJonathan T. Looney        return rv
65*631d525dSJonathan T. Looney    def __del__(self):
66*631d525dSJonathan T. Looney        for s in self.sockets:
67*631d525dSJonathan T. Looney            s.close()
68*631d525dSJonathan T. Looney        if self.ls is not None:
69*631d525dSJonathan T. Looney            self.ls.close()
70*631d525dSJonathan T. Looney
71*631d525dSJonathan T. Looneyclass IPv4Test(GenericTest):
72*631d525dSJonathan T. Looney    def __init__(self):
73*631d525dSJonathan T. Looney        super(IPv4Test, self).setup(socket.AF_INET, (V4HOST, TCPPORT))
74*631d525dSJonathan T. Looney
75*631d525dSJonathan T. Looneyclass IPv6Test(GenericTest):
76*631d525dSJonathan T. Looney    def __init__(self):
77*631d525dSJonathan T. Looney        super(IPv6Test, self).setup(socket.AF_INET6, (V6HOST, TCPPORT))
78*631d525dSJonathan T. Looney
79*631d525dSJonathan T. Looneyclass UnixTest(GenericTest):
80*631d525dSJonathan T. Looney    def __init__(self):
81*631d525dSJonathan T. Looney        super(UnixTest, self).setup(socket.AF_UNIX, UNIXSOCK)
82*631d525dSJonathan T. Looney    def __del__(self):
83*631d525dSJonathan T. Looney        super(UnixTest, self).__del__()
84*631d525dSJonathan T. Looney        os.remove(UNIXSOCK)
85*631d525dSJonathan T. Looney
86*631d525dSJonathan T. Looneyclass LogChecker():
87*631d525dSJonathan T. Looney    def __init__(self):
88*631d525dSJonathan T. Looney        # Figure out how big the dmesg buffer is.
89*631d525dSJonathan T. Looney        self.dmesgOff = len(check_output("/sbin/dmesg"))
90*631d525dSJonathan T. Looney
91*631d525dSJonathan T. Looney    def checkForMsg(self, expected):
92*631d525dSJonathan T. Looney        newOff = self.dmesgOff
93*631d525dSJonathan T. Looney        for i in range(0, 3):
94*631d525dSJonathan T. Looney            dmesg = check_output("/sbin/dmesg")
95*631d525dSJonathan T. Looney            newOff = len(dmesg)
96*631d525dSJonathan T. Looney            if newOff >= self.dmesgOff:
97*631d525dSJonathan T. Looney                dmesg = dmesg[self.dmesgOff:]
98*631d525dSJonathan T. Looney            for line in dmesg.splitlines():
99*631d525dSJonathan T. Looney                try:
100*631d525dSJonathan T. Looney                    if str(line).find(expected) >= 0:
101*631d525dSJonathan T. Looney                        self.dmesgOff = newOff
102*631d525dSJonathan T. Looney                        return True
103*631d525dSJonathan T. Looney                except:
104*631d525dSJonathan T. Looney                    pass
105*631d525dSJonathan T. Looney            sleep(0.5)
106*631d525dSJonathan T. Looney        self.dmesgOff = newOff
107*631d525dSJonathan T. Looney        return False
108*631d525dSJonathan T. Looney
109*631d525dSJonathan T. Looneydef main():
110*631d525dSJonathan T. Looney    ip4 = IPv4Test()
111*631d525dSJonathan T. Looney    ip6 = IPv6Test()
112*631d525dSJonathan T. Looney    lcl = UnixTest()
113*631d525dSJonathan T. Looney    lc = LogChecker()
114*631d525dSJonathan T. Looney    failure = False
115*631d525dSJonathan T. Looney
116*631d525dSJonathan T. Looney    STDLOGMSG = "Listen queue overflow: 4 already in queue awaiting acceptance (1 occurrences)"
117*631d525dSJonathan T. Looney
118*631d525dSJonathan T. Looney    V4LOGMSG = "(%s:%d (proto 6)): %s" % (V4HOST, TCPPORT, STDLOGMSG)
119*631d525dSJonathan T. Looney    ip4.doTest(5)
120*631d525dSJonathan T. Looney    if not lc.checkForMsg(V4LOGMSG):
121*631d525dSJonathan T. Looney        failure = True
122*631d525dSJonathan T. Looney        sys.stderr.write("IPv4 log message not seen\n")
123*631d525dSJonathan T. Looney    else:
124*631d525dSJonathan T. Looney        ip4.doTest(1)
125*631d525dSJonathan T. Looney        if lc.checkForMsg(V4LOGMSG):
126*631d525dSJonathan T. Looney            failure = True
127*631d525dSJonathan T. Looney            sys.stderr.write("Subsequent IPv4 log message not suppressed\n")
128*631d525dSJonathan T. Looney
129*631d525dSJonathan T. Looney    V6LOGMSG = "([%s]:%d (proto 6)): %s" % (V6HOST, TCPPORT, STDLOGMSG)
130*631d525dSJonathan T. Looney    ip6.doTest(5)
131*631d525dSJonathan T. Looney    if not lc.checkForMsg(V6LOGMSG):
132*631d525dSJonathan T. Looney        failure = True
133*631d525dSJonathan T. Looney        sys.stderr.write("IPv6 log message not seen\n")
134*631d525dSJonathan T. Looney    else:
135*631d525dSJonathan T. Looney        ip6.doTest(1)
136*631d525dSJonathan T. Looney        if lc.checkForMsg(V6LOGMSG):
137*631d525dSJonathan T. Looney            failure = True
138*631d525dSJonathan T. Looney            sys.stderr.write("Subsequent IPv6 log message not suppressed\n")
139*631d525dSJonathan T. Looney
140*631d525dSJonathan T. Looney    UNIXLOGMSG = "(local:%s): %s" % (UNIXSOCK, STDLOGMSG)
141*631d525dSJonathan T. Looney    lcl.doTest(5)
142*631d525dSJonathan T. Looney    if not lc.checkForMsg(UNIXLOGMSG):
143*631d525dSJonathan T. Looney        failure = True
144*631d525dSJonathan T. Looney        sys.stderr.write("Unix socket log message not seen\n")
145*631d525dSJonathan T. Looney    else:
146*631d525dSJonathan T. Looney        lcl.doTest(1)
147*631d525dSJonathan T. Looney        if lc.checkForMsg(UNIXLOGMSG):
148*631d525dSJonathan T. Looney            failure = True
149*631d525dSJonathan T. Looney            sys.stderr.write("Subsequent Unix socket log message not suppressed\n")
150*631d525dSJonathan T. Looney
151*631d525dSJonathan T. Looney    if failure:
152*631d525dSJonathan T. Looney        sys.exit(1)
153*631d525dSJonathan T. Looney    sys.exit(0)
154*631d525dSJonathan T. Looney
155*631d525dSJonathan T. Looneyif __name__ == '__main__':
156*631d525dSJonathan T. Looney    main()
157