xref: /freebsd/tests/sys/kern/sonewconn_overflow.py (revision 7862a433e947a78b44bce80bb7e00eeb44d752cd)
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# $FreeBSD$
29631d525dSJonathan T. Looney#
30631d525dSJonathan T. Looney
31631d525dSJonathan T. Looneyimport socket
32631d525dSJonathan T. Looneyimport os
33631d525dSJonathan T. Looneyimport sys
34631d525dSJonathan T. Looneyfrom subprocess import check_output
35631d525dSJonathan T. Looneyfrom time import sleep
36631d525dSJonathan T. Looney
37631d525dSJonathan T. LooneyV4HOST = '127.0.0.1'
38631d525dSJonathan T. LooneyV6HOST = '::1'
39631d525dSJonathan T. LooneyTCPPORT = 65432
40631d525dSJonathan T. LooneyUNIXSOCK = '/tmp/testsock'
41631d525dSJonathan T. LooneyTYPE = socket.SOCK_STREAM
42631d525dSJonathan T. Looney
43631d525dSJonathan T. Looneyclass GenericTest(object):
44631d525dSJonathan T. Looney    def __init__(self):
45631d525dSJonathan T. Looney        raise NotImplementedError("Subclass must override the __init__ method")
46631d525dSJonathan T. Looney    def setup(self, af, addr):
47631d525dSJonathan T. Looney        self.sockets = []
48631d525dSJonathan T. Looney        self.ls = None
49631d525dSJonathan T. Looney        self.ls = socket.socket(af, TYPE)
50631d525dSJonathan T. Looney        self.ls.bind(addr)
51631d525dSJonathan T. Looney        self.ls.listen(2)
52631d525dSJonathan T. Looney        self.af = af
53631d525dSJonathan T. Looney        self.addr = addr
54631d525dSJonathan T. Looney    def doTest(self, cnt):
55631d525dSJonathan T. Looney        rv = 0
56631d525dSJonathan T. Looney        for i in range(0, cnt):
57631d525dSJonathan T. Looney            try:
58631d525dSJonathan T. Looney                s = socket.socket(self.af, TYPE)
59631d525dSJonathan T. Looney                s.connect(self.addr)
60631d525dSJonathan T. Looney            except:
61631d525dSJonathan T. Looney                continue
62631d525dSJonathan T. Looney            self.sockets.append(s)
63631d525dSJonathan T. Looney            rv += 1
64631d525dSJonathan T. Looney        return rv
65631d525dSJonathan T. Looney    def __del__(self):
66631d525dSJonathan T. Looney        for s in self.sockets:
67631d525dSJonathan T. Looney            s.close()
68631d525dSJonathan T. Looney        if self.ls is not None:
69631d525dSJonathan T. Looney            self.ls.close()
70631d525dSJonathan T. Looney
71631d525dSJonathan T. Looneyclass IPv4Test(GenericTest):
72631d525dSJonathan T. Looney    def __init__(self):
73631d525dSJonathan T. Looney        super(IPv4Test, self).setup(socket.AF_INET, (V4HOST, TCPPORT))
74631d525dSJonathan T. Looney
75631d525dSJonathan T. Looneyclass IPv6Test(GenericTest):
76631d525dSJonathan T. Looney    def __init__(self):
77631d525dSJonathan T. Looney        super(IPv6Test, self).setup(socket.AF_INET6, (V6HOST, TCPPORT))
78631d525dSJonathan T. Looney
79631d525dSJonathan T. Looneyclass UnixTest(GenericTest):
80631d525dSJonathan T. Looney    def __init__(self):
81631d525dSJonathan T. Looney        super(UnixTest, self).setup(socket.AF_UNIX, UNIXSOCK)
82631d525dSJonathan T. Looney    def __del__(self):
83631d525dSJonathan T. Looney        super(UnixTest, self).__del__()
84631d525dSJonathan T. Looney        os.remove(UNIXSOCK)
85631d525dSJonathan T. Looney
86631d525dSJonathan T. Looneyclass LogChecker():
87631d525dSJonathan T. Looney    def __init__(self):
88*7862a433SLi-Wen Hsu        # Clear the dmesg buffer to prevent rotating causes issues
89*7862a433SLi-Wen Hsu        os.system('/sbin/dmesg -c > /dev/null')
90631d525dSJonathan T. Looney        # Figure out how big the dmesg buffer is.
91631d525dSJonathan T. Looney        self.dmesgOff = len(check_output("/sbin/dmesg"))
92631d525dSJonathan T. Looney
93631d525dSJonathan T. Looney    def checkForMsg(self, expected):
94631d525dSJonathan T. Looney        newOff = self.dmesgOff
95631d525dSJonathan T. Looney        for i in range(0, 3):
96631d525dSJonathan T. Looney            dmesg = check_output("/sbin/dmesg")
97631d525dSJonathan T. Looney            newOff = len(dmesg)
98631d525dSJonathan T. Looney            if newOff >= self.dmesgOff:
99631d525dSJonathan T. Looney                dmesg = dmesg[self.dmesgOff:]
100631d525dSJonathan T. Looney            for line in dmesg.splitlines():
101631d525dSJonathan T. Looney                try:
102631d525dSJonathan T. Looney                    if str(line).find(expected) >= 0:
103631d525dSJonathan T. Looney                        self.dmesgOff = newOff
104631d525dSJonathan T. Looney                        return True
105631d525dSJonathan T. Looney                except:
106631d525dSJonathan T. Looney                    pass
107631d525dSJonathan T. Looney            sleep(0.5)
108631d525dSJonathan T. Looney        self.dmesgOff = newOff
109631d525dSJonathan T. Looney        return False
110631d525dSJonathan T. Looney
111631d525dSJonathan T. Looneydef main():
112631d525dSJonathan T. Looney    ip4 = IPv4Test()
113631d525dSJonathan T. Looney    ip6 = IPv6Test()
114631d525dSJonathan T. Looney    lcl = UnixTest()
115631d525dSJonathan T. Looney    lc = LogChecker()
116631d525dSJonathan T. Looney    failure = False
117631d525dSJonathan T. Looney
118631d525dSJonathan T. Looney    STDLOGMSG = "Listen queue overflow: 4 already in queue awaiting acceptance (1 occurrences)"
119631d525dSJonathan T. Looney
120631d525dSJonathan T. Looney    V4LOGMSG = "(%s:%d (proto 6)): %s" % (V4HOST, TCPPORT, STDLOGMSG)
121631d525dSJonathan T. Looney    ip4.doTest(5)
122631d525dSJonathan T. Looney    if not lc.checkForMsg(V4LOGMSG):
123631d525dSJonathan T. Looney        failure = True
124631d525dSJonathan T. Looney        sys.stderr.write("IPv4 log message not seen\n")
125631d525dSJonathan T. Looney    else:
126631d525dSJonathan T. Looney        ip4.doTest(1)
127631d525dSJonathan T. Looney        if lc.checkForMsg(V4LOGMSG):
128631d525dSJonathan T. Looney            failure = True
129631d525dSJonathan T. Looney            sys.stderr.write("Subsequent IPv4 log message not suppressed\n")
130631d525dSJonathan T. Looney
131631d525dSJonathan T. Looney    V6LOGMSG = "([%s]:%d (proto 6)): %s" % (V6HOST, TCPPORT, STDLOGMSG)
132631d525dSJonathan T. Looney    ip6.doTest(5)
133631d525dSJonathan T. Looney    if not lc.checkForMsg(V6LOGMSG):
134631d525dSJonathan T. Looney        failure = True
135631d525dSJonathan T. Looney        sys.stderr.write("IPv6 log message not seen\n")
136631d525dSJonathan T. Looney    else:
137631d525dSJonathan T. Looney        ip6.doTest(1)
138631d525dSJonathan T. Looney        if lc.checkForMsg(V6LOGMSG):
139631d525dSJonathan T. Looney            failure = True
140631d525dSJonathan T. Looney            sys.stderr.write("Subsequent IPv6 log message not suppressed\n")
141631d525dSJonathan T. Looney
142631d525dSJonathan T. Looney    UNIXLOGMSG = "(local:%s): %s" % (UNIXSOCK, STDLOGMSG)
143631d525dSJonathan T. Looney    lcl.doTest(5)
144631d525dSJonathan T. Looney    if not lc.checkForMsg(UNIXLOGMSG):
145631d525dSJonathan T. Looney        failure = True
146631d525dSJonathan T. Looney        sys.stderr.write("Unix socket log message not seen\n")
147631d525dSJonathan T. Looney    else:
148631d525dSJonathan T. Looney        lcl.doTest(1)
149631d525dSJonathan T. Looney        if lc.checkForMsg(UNIXLOGMSG):
150631d525dSJonathan T. Looney            failure = True
151631d525dSJonathan T. Looney            sys.stderr.write("Subsequent Unix socket log message not suppressed\n")
152631d525dSJonathan T. Looney
153631d525dSJonathan T. Looney    if failure:
154631d525dSJonathan T. Looney        sys.exit(1)
155631d525dSJonathan T. Looney    sys.exit(0)
156631d525dSJonathan T. Looney
157631d525dSJonathan T. Looneyif __name__ == '__main__':
158631d525dSJonathan T. Looney    main()
159