xref: /freebsd/tests/sys/kern/sonewconn_overflow.py (revision d0b2dbfa0ecf2bbc9709efc5e20baf8e4b44bbbf)
1631d525dSJonathan T. Looney#!/usr/bin/env python
2631d525dSJonathan T. Looney#-
3631d525dSJonathan T. Looney# SPDX-License-Identifier: BSD-2-Clause
4631d525dSJonathan T. Looney#
5631d525dSJonathan T. Looney# Copyright (c) 2020 Netflix, Inc.
6631d525dSJonathan T. Looney#
7631d525dSJonathan T. Looney# Redistribution and use in source and binary forms, with or without
8631d525dSJonathan T. Looney# modification, are permitted provided that the following conditions
9631d525dSJonathan T. Looney# are met:
10631d525dSJonathan T. Looney# 1. Redistributions of source code must retain the above copyright
11631d525dSJonathan T. Looney#    notice, this list of conditions and the following disclaimer.
12631d525dSJonathan T. Looney# 2. Redistributions in binary form must reproduce the above copyright
13631d525dSJonathan T. Looney#    notice, this list of conditions and the following disclaimer in the
14631d525dSJonathan T. Looney#    documentation and/or other materials provided with the distribution.
15631d525dSJonathan T. Looney#
16631d525dSJonathan T. Looney# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17631d525dSJonathan T. Looney# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18631d525dSJonathan T. Looney# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19631d525dSJonathan T. Looney# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20631d525dSJonathan T. Looney# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21631d525dSJonathan T. Looney# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22631d525dSJonathan T. Looney# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23631d525dSJonathan T. Looney# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24631d525dSJonathan T. Looney# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25631d525dSJonathan T. Looney# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26631d525dSJonathan T. Looney# SUCH DAMAGE.
27631d525dSJonathan T. Looney#
28631d525dSJonathan T. Looney#
29631d525dSJonathan T. Looney
30631d525dSJonathan T. Looneyimport socket
31631d525dSJonathan T. Looneyimport os
32631d525dSJonathan T. Looneyimport sys
33631d525dSJonathan T. Looneyfrom subprocess import check_output
34631d525dSJonathan T. Looneyfrom time import sleep
35631d525dSJonathan T. Looney
36631d525dSJonathan T. LooneyV4HOST = '127.0.0.1'
37631d525dSJonathan T. LooneyV6HOST = '::1'
38631d525dSJonathan T. LooneyTCPPORT = 65432
39631d525dSJonathan T. LooneyUNIXSOCK = '/tmp/testsock'
40631d525dSJonathan T. LooneyTYPE = socket.SOCK_STREAM
41631d525dSJonathan T. Looney
42631d525dSJonathan T. Looneyclass GenericTest(object):
43631d525dSJonathan T. Looney    def __init__(self):
44631d525dSJonathan T. Looney        raise NotImplementedError("Subclass must override the __init__ method")
45631d525dSJonathan T. Looney    def setup(self, af, addr):
46631d525dSJonathan T. Looney        self.sockets = []
47631d525dSJonathan T. Looney        self.ls = None
48631d525dSJonathan T. Looney        self.ls = socket.socket(af, TYPE)
49631d525dSJonathan T. Looney        self.ls.bind(addr)
50631d525dSJonathan T. Looney        self.ls.listen(2)
51631d525dSJonathan T. Looney        self.af = af
52631d525dSJonathan T. Looney        self.addr = addr
53631d525dSJonathan T. Looney    def doTest(self, cnt):
54631d525dSJonathan T. Looney        rv = 0
55631d525dSJonathan T. Looney        for i in range(0, cnt):
56631d525dSJonathan T. Looney            try:
57631d525dSJonathan T. Looney                s = socket.socket(self.af, TYPE)
58631d525dSJonathan T. Looney                s.connect(self.addr)
59631d525dSJonathan T. Looney            except:
60631d525dSJonathan T. Looney                continue
61631d525dSJonathan T. Looney            self.sockets.append(s)
62631d525dSJonathan T. Looney            rv += 1
63631d525dSJonathan T. Looney        return rv
64631d525dSJonathan T. Looney    def __del__(self):
65631d525dSJonathan T. Looney        for s in self.sockets:
66631d525dSJonathan T. Looney            s.close()
67631d525dSJonathan T. Looney        if self.ls is not None:
68631d525dSJonathan T. Looney            self.ls.close()
69631d525dSJonathan T. Looney
70631d525dSJonathan T. Looneyclass IPv4Test(GenericTest):
71631d525dSJonathan T. Looney    def __init__(self):
72631d525dSJonathan T. Looney        super(IPv4Test, self).setup(socket.AF_INET, (V4HOST, TCPPORT))
73631d525dSJonathan T. Looney
74631d525dSJonathan T. Looneyclass IPv6Test(GenericTest):
75631d525dSJonathan T. Looney    def __init__(self):
76631d525dSJonathan T. Looney        super(IPv6Test, self).setup(socket.AF_INET6, (V6HOST, TCPPORT))
77631d525dSJonathan T. Looney
78631d525dSJonathan T. Looneyclass UnixTest(GenericTest):
79631d525dSJonathan T. Looney    def __init__(self):
80631d525dSJonathan T. Looney        super(UnixTest, self).setup(socket.AF_UNIX, UNIXSOCK)
81631d525dSJonathan T. Looney    def __del__(self):
82631d525dSJonathan T. Looney        super(UnixTest, self).__del__()
83631d525dSJonathan T. Looney        os.remove(UNIXSOCK)
84631d525dSJonathan T. Looney
85631d525dSJonathan T. Looneyclass LogChecker():
86631d525dSJonathan T. Looney    def __init__(self):
87*7862a433SLi-Wen Hsu        # Clear the dmesg buffer to prevent rotating causes issues
88*7862a433SLi-Wen Hsu        os.system('/sbin/dmesg -c > /dev/null')
89631d525dSJonathan T. Looney        # Figure out how big the dmesg buffer is.
90631d525dSJonathan T. Looney        self.dmesgOff = len(check_output("/sbin/dmesg"))
91631d525dSJonathan T. Looney
92631d525dSJonathan T. Looney    def checkForMsg(self, expected):
93631d525dSJonathan T. Looney        newOff = self.dmesgOff
94631d525dSJonathan T. Looney        for i in range(0, 3):
95631d525dSJonathan T. Looney            dmesg = check_output("/sbin/dmesg")
96631d525dSJonathan T. Looney            newOff = len(dmesg)
97631d525dSJonathan T. Looney            if newOff >= self.dmesgOff:
98631d525dSJonathan T. Looney                dmesg = dmesg[self.dmesgOff:]
99631d525dSJonathan T. Looney            for line in dmesg.splitlines():
100631d525dSJonathan T. Looney                try:
101631d525dSJonathan T. Looney                    if str(line).find(expected) >= 0:
102631d525dSJonathan T. Looney                        self.dmesgOff = newOff
103631d525dSJonathan T. Looney                        return True
104631d525dSJonathan T. Looney                except:
105631d525dSJonathan T. Looney                    pass
106631d525dSJonathan T. Looney            sleep(0.5)
107631d525dSJonathan T. Looney        self.dmesgOff = newOff
108631d525dSJonathan T. Looney        return False
109631d525dSJonathan T. Looney
110631d525dSJonathan T. Looneydef main():
111631d525dSJonathan T. Looney    ip4 = IPv4Test()
112631d525dSJonathan T. Looney    ip6 = IPv6Test()
113631d525dSJonathan T. Looney    lcl = UnixTest()
114631d525dSJonathan T. Looney    lc = LogChecker()
115631d525dSJonathan T. Looney    failure = False
116631d525dSJonathan T. Looney
117631d525dSJonathan T. Looney    STDLOGMSG = "Listen queue overflow: 4 already in queue awaiting acceptance (1 occurrences)"
118631d525dSJonathan T. Looney
119631d525dSJonathan T. Looney    V4LOGMSG = "(%s:%d (proto 6)): %s" % (V4HOST, TCPPORT, STDLOGMSG)
120631d525dSJonathan T. Looney    ip4.doTest(5)
121631d525dSJonathan T. Looney    if not lc.checkForMsg(V4LOGMSG):
122631d525dSJonathan T. Looney        failure = True
123631d525dSJonathan T. Looney        sys.stderr.write("IPv4 log message not seen\n")
124631d525dSJonathan T. Looney    else:
125631d525dSJonathan T. Looney        ip4.doTest(1)
126631d525dSJonathan T. Looney        if lc.checkForMsg(V4LOGMSG):
127631d525dSJonathan T. Looney            failure = True
128631d525dSJonathan T. Looney            sys.stderr.write("Subsequent IPv4 log message not suppressed\n")
129631d525dSJonathan T. Looney
130631d525dSJonathan T. Looney    V6LOGMSG = "([%s]:%d (proto 6)): %s" % (V6HOST, TCPPORT, STDLOGMSG)
131631d525dSJonathan T. Looney    ip6.doTest(5)
132631d525dSJonathan T. Looney    if not lc.checkForMsg(V6LOGMSG):
133631d525dSJonathan T. Looney        failure = True
134631d525dSJonathan T. Looney        sys.stderr.write("IPv6 log message not seen\n")
135631d525dSJonathan T. Looney    else:
136631d525dSJonathan T. Looney        ip6.doTest(1)
137631d525dSJonathan T. Looney        if lc.checkForMsg(V6LOGMSG):
138631d525dSJonathan T. Looney            failure = True
139631d525dSJonathan T. Looney            sys.stderr.write("Subsequent IPv6 log message not suppressed\n")
140631d525dSJonathan T. Looney
141631d525dSJonathan T. Looney    UNIXLOGMSG = "(local:%s): %s" % (UNIXSOCK, STDLOGMSG)
142631d525dSJonathan T. Looney    lcl.doTest(5)
143631d525dSJonathan T. Looney    if not lc.checkForMsg(UNIXLOGMSG):
144631d525dSJonathan T. Looney        failure = True
145631d525dSJonathan T. Looney        sys.stderr.write("Unix socket log message not seen\n")
146631d525dSJonathan T. Looney    else:
147631d525dSJonathan T. Looney        lcl.doTest(1)
148631d525dSJonathan T. Looney        if lc.checkForMsg(UNIXLOGMSG):
149631d525dSJonathan T. Looney            failure = True
150631d525dSJonathan T. Looney            sys.stderr.write("Subsequent Unix socket log message not suppressed\n")
151631d525dSJonathan T. Looney
152631d525dSJonathan T. Looney    if failure:
153631d525dSJonathan T. Looney        sys.exit(1)
154631d525dSJonathan T. Looney    sys.exit(0)
155631d525dSJonathan T. Looney
156631d525dSJonathan T. Looneyif __name__ == '__main__':
157631d525dSJonathan T. Looney    main()
158