[Midnightbsd-cvs] src [11941] trunk/tools/tools/netrate/tcpp: tcpp

laffer1 at midnightbsd.org laffer1 at midnightbsd.org
Sat Jul 21 16:03:51 EDT 2018


Revision: 11941
          http://svnweb.midnightbsd.org/src/?rev=11941
Author:   laffer1
Date:     2018-07-21 16:03:50 -0400 (Sat, 21 Jul 2018)
Log Message:
-----------
tcpp

Added Paths:
-----------
    trunk/tools/tools/netrate/tcpp/
    trunk/tools/tools/netrate/tcpp/Makefile
    trunk/tools/tools/netrate/tcpp/README
    trunk/tools/tools/netrate/tcpp/parallelism.csh
    trunk/tools/tools/netrate/tcpp/runit.pl
    trunk/tools/tools/netrate/tcpp/tcpp.c
    trunk/tools/tools/netrate/tcpp/tcpp.h
    trunk/tools/tools/netrate/tcpp/tcpp_client.c
    trunk/tools/tools/netrate/tcpp/tcpp_server.c
    trunk/tools/tools/netrate/tcpp/tcpp_util.c

Added: trunk/tools/tools/netrate/tcpp/Makefile
===================================================================
--- trunk/tools/tools/netrate/tcpp/Makefile	                        (rev 0)
+++ trunk/tools/tools/netrate/tcpp/Makefile	2018-07-21 20:03:50 UTC (rev 11941)
@@ -0,0 +1,10 @@
+# $MidnightBSD$
+# $FreeBSD: stable/10/tools/tools/netrate/tcpp/Makefile 276486 2014-12-31 23:25:37Z ngie $
+
+PROG=	tcpp
+INCS=	tcpp.h
+MAN=
+SRCS=	tcpp.c tcpp_client.c tcpp_server.c tcpp_util.c
+WARNS?=	3
+
+.include <bsd.prog.mk>


Property changes on: trunk/tools/tools/netrate/tcpp/Makefile
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/tools/tools/netrate/tcpp/README
===================================================================
--- trunk/tools/tools/netrate/tcpp/README	                        (rev 0)
+++ trunk/tools/tools/netrate/tcpp/README	2018-07-21 20:03:50 UTC (rev 11941)
@@ -0,0 +1,108 @@
+tcpp -- Parallel TCP Exercise Tool
+
+This is a new tool, and is rife with bugs.  However, it appears to create
+even more problems for device drivers and the kernel, so that's OK.
+
+This tool generates large numbers of TCP connections and stuffs lots of data
+into them.  One binary encapsulates both a client and a server.  Each of the
+client and the server generates a certain number of worker processes, each of
+which in turn uses its own TCP port.  The number of server processes must be
+>= the number of client processes, or some of the ports required by the
+client won't have a listener.  The client then proceeds to make connections 
+and send data to the server.  Each worker multiplexes many connections at
+once, up to a maximum parallelism limit.  The client can use one or many IP
+addresses, in order to make more 4-tuples available for testing, and will
+automatically spread the load of new connections across available source
+addresses.
+
+You will need to retune your TCP stack for high volume, see Configuration
+Notes below.
+
+The server has very little to configure, use the following command line
+flags:
+
+  -s                           Select server mode
+  -p <numprocs>                Number of workers, should be >= client -p arg
+  -r <baseport>                Non-default base TCP port, should match client
+  -T                           Print CPU usage every ten seconds
+  -m <maxconnectionsperproc>   Maximum simultaneous connections/proc, should
+                               be >= client setting.
+
+Typical use:
+
+  ./tcpp -s -p 4 -m 1000000
+
+This selects server mode, four workers, and at most 1 million TCP connections
+per worker at a time.
+
+The client has more to configure, with the following flags:
+
+  -c <remoteIP>                Select client mode, and specific dest IP
+  -C                           Print connections/second instead of GBps
+  -P                           Pin each worker to a CPU
+  -M <localIPcount>            Number of sequential local IPs to use; req. -l
+  -T                           Include CPU use summary in stats at end of run
+  -b <bytespertcp>             Data bytes per connection
+  -l <localIPbase>             Starting local IP address to bind
+  -m <maxtcpsatonce>           Max simultaneous conn/worker (see server -m)
+  -p <numprocs>                Number of workers, should be <= server -p
+  -r <baseport>                Non-default base TCP port, should match server
+  -t <tcpsperproc>             How many connections to use per worker
+  
+Typical use:
+
+  ./tcpp -c 192.168.100.201 -p 4 -t 100000 -m 10000 -b 100000 \
+    -l 192.168.100.101 -M 4
+
+This creates four workers, each of which will (over its lifetime) set up and
+use 100,000 TCP connections carrying 100K of data, up to 10,000 simultaneous
+connection at any given moment.  tcpp will use four source IP addresses,
+starting with 192.168.100.101, and all connections will be to the single
+destination IP of 192.168.100.201.
+
+Having (p) <= the number of cores is advisable.  When multiple IPs are used
+on the client, they will be sequential starting with the localIPbase set with
+-l.
+
+Known Issues
+------------
+
+The bandwidth estimate doesn't handle failures well.  It also has serious
+rounding errors and probably conceptual problems.
+
+It's not clear that kevent() is "fair" to multiple connections.
+
+Rather than passing the length for each connection, we might want to pass
+it once with a control connection up front.  On the other hand, the server
+is quite dumb right now, so we could take advantage of this to do size
+mixes.
+
+Configuration Notes
+-------------------
+
+In my testing, I use loader.conf entries of:
+
+kern.ipc.maxsockets=1000000
+net.inet.tcp.maxtcptw=3000000
+kern.ipc.somaxconn=49152
+kern.ipc.nmbjumbo16=262144
+kern.ipc.nmbjumbo9=262144
+kern.ipc.nmbjumbop=262144
+kern.ipc.nmbclusters=262144
+net.inet.tcp.syncache.cachelimit=65536
+net.inet.tcp.syncache.bucketlimit=512
+
+# May be useful if you can't use multiple IP addresses
+net.inet.ip.portrange.first=100
+
+# For running !multiq, do this before loading the driver:
+kenv hw.cxgb.singleq="1"
+
+kldload if_cxgb
+
+# Consider turning off TSO and/or adjusting the MTU for some scenarios:
+ifconfig cxgb0 -tso
+ifconfig cxgb0 mtu 1500
+
+
+$MidnightBSD$


Property changes on: trunk/tools/tools/netrate/tcpp/README
___________________________________________________________________
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/tools/tools/netrate/tcpp/parallelism.csh
===================================================================
--- trunk/tools/tools/netrate/tcpp/parallelism.csh	                        (rev 0)
+++ trunk/tools/tools/netrate/tcpp/parallelism.csh	2018-07-21 20:03:50 UTC (rev 11941)
@@ -0,0 +1,28 @@
+#!/bin/csh
+#
+# $MidnightBSD$
+#
+# Run tcpp -s -p 8 on the server, then this on the client.
+#
+# Note awkwardly hard-coded IP address below.
+#
+# Accepts two arguments: [filename] [csvprefix]
+#
+
+set totalbytes=4800000		# Bytes per connection
+set cores=8
+set trials=6
+set ptcps=24			# Max TCPs concurrently
+set ntcps=240			# Total TCPs over test
+set nips=4			# Number of local IP addresses to use
+set baseip=192.168.100.200	# First IP address to use
+
+foreach core (`jot $cores`)
+  foreach trial (`jot $trials`)
+    set mflag=`echo $ptcps / $core | bc`
+    set tflag=`echo $ntcps / $core | bc`
+    echo -n $2,${core},${trial}, >> $1
+    ./tcpp -c 192.168.100.102 -p $core -b $totalbytes -m $mflag \
+      -t $tflag -M $nips -l $baseip >> $1
+  end
+end


Property changes on: trunk/tools/tools/netrate/tcpp/parallelism.csh
___________________________________________________________________
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/tools/tools/netrate/tcpp/runit.pl
===================================================================
--- trunk/tools/tools/netrate/tcpp/runit.pl	                        (rev 0)
+++ trunk/tools/tools/netrate/tcpp/runit.pl	2018-07-21 20:03:50 UTC (rev 11941)
@@ -0,0 +1,64 @@
+#!/usr/bin/perl
+#
+# $MidnightBSD$
+#
+
+if ($#ARGV != 0) {
+	print "runit.pl kernelname\n";
+	exit(-1);
+}
+
+$tcpp_dir = "/rwatson/svn/base/head/tools/tools/netrate/tcpp";
+
+($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
+$mon++;
+$year += 1900;
+$date = sprintf("%04d%02d%02d", $year, $mon, $mday);
+
+$kernel = $ARGV[0];
+$outfile = $date."_".$kernel.".csv";
+unlink($outfile);
+open(OUTFILE, ">".$outfile) || die $outfile;
+print OUTFILE "# $kernel $date\n";
+print OUTFILE "# hydra1: ".`ssh root\@hydra1 uname -a`."\n";
+print OUTFILE "# hydra2: ".`ssh root\@hydra2 uname -a`."\n";
+print OUTFILE "#\n";
+print OUTFILE "kernel,tso,lro,mtu,cores,trial,";
+print OUTFILE "bytes,seconds,conns,bandwidth,user,nice,sys,intr,idle\n";
+close(OUTFILE);
+
+system("ssh root\@hydra1 killall tcpp");
+system("ssh root\@hydra2 killall tcpp");
+sleep(1);
+system("ssh root\@hydra2 ${tcpp_dir}/tcpp -s -p 8&");
+sleep(1);
+
+sub test {
+	my ($kernel, $tso, $lro, $mtu) = @_;
+
+	$prefix = "$kernel,$tso,$lro,$mtu";
+	print "Configuring $prefix\n";
+
+	system("ssh root\@hydra1 ifconfig cxgb0 $tso $lro mtu $mtu");
+
+	system("ssh root\@hydra2 ifconfig cxgb0 $tso $lro mtu $mtu");
+
+	print "Running $prefix\n";
+	system("ssh root\@hydra1 '(cd $tcpp_dir ; csh parallelism.csh ".
+	    "$outfile $prefix)'");
+}
+
+# Frobbing MTU requires resetting the host cache, which we don't do,
+# so don't frob MTU.
+ at mtu_options = ("1500");
+ at tso_options = ("tso", "-tso");
+ at lro_options = ("lro", "-lro");
+
+foreach $mtu (@mtu_options) {
+	foreach $tso (@tso_options) {
+		foreach $lro (@lro_options) {
+			sleep(5);
+			test($kernel, $tso, $lro, $mtu);
+		}
+	}
+}


Property changes on: trunk/tools/tools/netrate/tcpp/runit.pl
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/tools/tools/netrate/tcpp/tcpp.c
===================================================================
--- trunk/tools/tools/netrate/tcpp/tcpp.c	                        (rev 0)
+++ trunk/tools/tools/netrate/tcpp/tcpp.c	2018-07-21 20:03:50 UTC (rev 11941)
@@ -0,0 +1,213 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2008-2009 Robert N. M. Watson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD: stable/10/tools/tools/netrate/tcpp/tcpp.c 208873 2010-06-06 15:27:08Z rwatson $
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+
+#include <arpa/inet.h>
+
+#include <err.h>
+#include <getopt.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sysexits.h>
+#include <unistd.h>
+
+#include "tcpp.h"
+
+#define	BYTES_DEFAULT	10*1024*1024	/* Data per connection. */
+#define	MAXTCPS_DEFAULT	32		/* Number of TCPs at a time per proc. */
+#define	PROCS_DEFAULT	1		/* Processes used in run. */
+#define	TCPS_DEFAULT	1		/* Number of connections per process. */
+#define	BASEPORT_DEFAULT	10000
+
+struct sockaddr_in remoteip; 		/* Base target address. */
+struct sockaddr_in localipbase;		/* Base local address, if -l. */
+int cflag, hflag, lflag, mflag, pflag, sflag, tflag, Mflag, Pflag;
+uint64_t bflag;
+u_short rflag;
+
+static void
+usage(void)
+{
+
+	fprintf(stderr, "client: tcpp"
+	    " -c remoteIP"
+	    " [-h]"
+	    " [-P]"
+	    " [-M localIPcount]"
+	    " [-l localIPbase]"
+	    "\n\t"
+	    " [-b bytespertcp]"
+	    " [-m maxtcpsatonce]"
+	    " [-p procs]"
+	    " [-t tcpsperproc]"
+	    "\n"
+	    "\t"
+	    " [-r baseport]"
+	    "\n");
+
+	fprintf(stderr, "server: tcpp"
+	    " -s"
+	    " [-P]"
+	    " [-l localIPbase]"
+	    " [-m maxtcpsatonce]"
+	    " [-p procs]"
+	    "\n"
+	    "\t"
+	    " [-r baseport]"
+	    "\n");
+	exit(EX_USAGE);
+}
+
+int
+main(int argc, char *argv[])
+{
+	long long ll;
+	char *dummy;
+	int ch;
+
+	bzero(&localipbase, sizeof(localipbase));
+	localipbase.sin_len = sizeof(localipbase);
+	localipbase.sin_family = AF_INET;
+	localipbase.sin_addr.s_addr = htonl(INADDR_ANY);	/* Default. */
+	localipbase.sin_port = htons(0);				/* Default. */
+
+	bzero(&remoteip, sizeof(remoteip));
+	remoteip.sin_len = sizeof(remoteip);
+	remoteip.sin_family = AF_INET;
+	remoteip.sin_addr.s_addr = htonl(INADDR_LOOPBACK); /* Default. */
+	remoteip.sin_port = htons(0);				/* Default. */
+
+	bflag = BYTES_DEFAULT;
+	mflag = MAXTCPS_DEFAULT;
+	pflag = PROCS_DEFAULT;
+	rflag = BASEPORT_DEFAULT;
+	tflag = TCPS_DEFAULT;
+	Mflag = 1;
+	while ((ch = getopt(argc, argv, "b:c:hl:m:p:r:st:CM:PT")) != -1) {
+		switch (ch) {
+		case 'b':
+			ll = strtoll(optarg, &dummy, 10);
+			if (*dummy != '\0' || ll <= 0)
+				usage();
+			bflag = ll;
+			break;
+
+		case 'c':
+			cflag++;
+			if (inet_aton(optarg, &remoteip.sin_addr) != 1)
+				err(-1, "inet_aton: %s", optarg);
+			break;
+
+		case 'h':
+			hflag++;
+			break;
+
+		case 'l':
+			lflag++;
+			if (inet_aton(optarg, &localipbase.sin_addr) != 1)
+				err(-1, "inet_aton: %s", optarg);
+			break;
+
+		case 'm':
+			ll = strtoll(optarg, &dummy, 10);
+			if (*dummy != '\0' || ll <= 0)
+				usage();
+			mflag = ll;
+			break;
+
+		case 'p':
+			ll = strtoll(optarg, &dummy, 10);
+			if (*dummy != '\0' || ll <= 0)
+				usage();
+			pflag = ll;
+			break;
+
+		case 'r':
+			ll = strtol(optarg, &dummy, 10);
+			if (*dummy != '\0' || ll < 1 || ll > 65535)
+				usage();
+			rflag = ll;
+			break;
+
+		case 's':
+			sflag++;
+			break;
+
+		case 't':
+			ll = strtoll(optarg, &dummy, 10);
+			if (*dummy != '\0' || ll <= 0)
+				usage();
+			tflag = ll;
+			break;
+
+		case 'M':
+			ll = strtoll(optarg, &dummy, 10);
+			if (*dummy != '\0' || ll <= 1)
+				usage();
+			Mflag = ll;
+			break;
+
+		case 'P':
+#if defined(CPU_SETSIZE) && 0
+			Pflag++;
+			break;
+#else
+			errx(EX_USAGE, "-P current unsupported");
+#endif
+
+		default:
+			usage();
+		}
+	}
+
+	/* Exactly one of client and server. */
+	if (cflag > 1 || sflag > 1)
+		usage();
+	if ((cflag && sflag) || (!cflag && !sflag))
+		usage();
+
+	/* If Mflag is specified, we must have the lflag for a local IP. */
+	if (Mflag > 1 && !lflag)
+		usage();
+
+	/* Several flags are valid only on the client, disallow if server. */
+	if (sflag && (hflag || Mflag > 1))
+		usage();
+
+	if (cflag)
+		tcpp_client();
+	else
+		tcpp_server();
+	exit(0);
+}


Property changes on: trunk/tools/tools/netrate/tcpp/tcpp.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/tools/tools/netrate/tcpp/tcpp.h
===================================================================
--- trunk/tools/tools/netrate/tcpp/tcpp.h	                        (rev 0)
+++ trunk/tools/tools/netrate/tcpp/tcpp.h	2018-07-21 20:03:50 UTC (rev 11941)
@@ -0,0 +1,53 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2008-2009 Robert N. M. Watson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD: stable/10/tools/tools/netrate/tcpp/tcpp.h 208873 2010-06-06 15:27:08Z rwatson $
+ */
+
+#ifndef TCPP_H
+#define	TCPP_H
+
+extern struct sockaddr_in localipbase, remoteip;
+extern int cflag, hflag, lflag, mflag, pflag, sflag, tflag;
+extern int Iflag, Mflag, Pflag;
+extern uint64_t bflag;
+extern u_short rflag;
+
+#define	TCPP_MAGIC	0x84e812f7
+struct tcpp_header {
+	u_int32_t	th_magic;
+	u_int64_t	th_len;
+} __packed;
+
+void	tcpp_client(void);
+void	tcpp_header_encode(struct tcpp_header *thp);
+void	tcpp_header_decode(struct tcpp_header *thp);
+void	tcpp_server(void);
+
+#define	SYSCTLNAME_CPUS		"kern.smp.cpus"
+#define	SYSCTLNAME_CPTIME	"kern.cp_time"
+
+#endif /* TCPP_H */


Property changes on: trunk/tools/tools/netrate/tcpp/tcpp.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/tools/tools/netrate/tcpp/tcpp_client.c
===================================================================
--- trunk/tools/tools/netrate/tcpp/tcpp_client.c	                        (rev 0)
+++ trunk/tools/tools/netrate/tcpp/tcpp_client.c	2018-07-21 20:03:50 UTC (rev 11941)
@@ -0,0 +1,378 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2008-2009 Robert N. M. Watson
+ * Copyright (c) 2010 Juniper Networks, Inc.
+ * All rights reserved.
+ *
+ * This software was developed by Robert N. M. Watson under contract
+ * to Juniper Networks, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD: stable/10/tools/tools/netrate/tcpp/tcpp_client.c 228956 2011-12-29 15:34:59Z rwatson $
+ */
+
+#include <sys/types.h>
+#include <sys/event.h>
+#include <sys/resource.h>
+#include <sys/sched.h>
+#include <sys/socket.h>
+#include <sys/sysctl.h>
+#include <sys/time.h>
+#include <sys/uio.h>
+#include <sys/wait.h>
+
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "tcpp.h"
+
+#define	min(x, y)	(x < y ? x : y)
+
+#define timespecsub(vvp, uvp)						\
+	do {								\
+		(vvp)->tv_sec -= (uvp)->tv_sec;				\
+		(vvp)->tv_nsec -= (uvp)->tv_nsec;			\
+		if ((vvp)->tv_nsec < 0) {				\
+			(vvp)->tv_sec--;				\
+			(vvp)->tv_nsec += 1000000000;			\
+		}							\
+	} while (0)
+
+
+/*
+ * Gist of each client worker: build up to mflag connections at a time, and
+ * pump data in to them somewhat fairly until tflag connections have been
+ * completed.
+ */
+#define	CONNECTION_MAGIC	0x87a3f56e
+struct connection {
+	uint32_t	conn_magic;		/* Just magic. */
+	int		conn_fd;
+	struct tcpp_header	conn_header;	/* Header buffer. */
+	u_int		conn_header_sent;	/* Header bytes sent. */
+	u_int64_t	conn_data_sent;		/* Data bytes sent.*/
+};
+
+static u_char			 buffer[256 * 1024];	/* Buffer to send. */
+static pid_t			*pid_list;
+static int			 kq;
+static int			 started;	/* Number started so far. */
+static int			 finished;	/* Number finished so far. */
+static int			 counter;	/* IP number offset. */
+static uint64_t			 payload_len;
+
+static struct connection *
+tcpp_client_newconn(void)
+{
+	struct sockaddr_in sin;
+	struct connection *conn;
+	struct kevent kev;
+	int fd, i;
+
+	/*
+	 * Spread load over available IPs, rotating through them as we go.  No
+	 * attempt to localize IPs to particular workers.
+	 */
+	sin = localipbase;
+	sin.sin_addr.s_addr = htonl(ntohl(localipbase.sin_addr.s_addr) +
+	    (counter++ % Mflag));
+
+	fd = socket(PF_INET, SOCK_STREAM, 0);
+	if (fd < 0)
+		err(-1, "socket");
+
+	if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0)
+		err(-1, "fcntl");
+
+	i = 1;
+	if (setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, &i, sizeof(i)) < 0)
+		err(-1, "setsockopt");
+	i = 1;
+	if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &i, sizeof(i)) < 0)
+		err(-1, "setsockopt");
+#if 0
+	i = 1;
+	if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i)) < 0)
+		err(-1, "setsockopt");
+#endif
+
+	if (lflag) {
+		if (bind(fd, (struct sockaddr *)&sin, sizeof(sin)) < 0)
+			err(-1, "bind");
+	}
+
+	if (connect(fd, (struct sockaddr *)&remoteip, sizeof(remoteip)) < 0 &&
+	    errno != EINPROGRESS)
+		err(-1, "connect");
+
+	conn = malloc(sizeof(*conn));
+	if (conn == NULL)
+		return (NULL);
+	bzero(conn, sizeof(*conn));
+	conn->conn_magic = CONNECTION_MAGIC;
+	conn->conn_fd = fd;
+	conn->conn_header.th_magic = TCPP_MAGIC;
+	conn->conn_header.th_len = payload_len;
+	tcpp_header_encode(&conn->conn_header);
+
+	EV_SET(&kev, fd, EVFILT_WRITE, EV_ADD, 0, 0, conn);
+	if (kevent(kq, &kev, 1, NULL, 0, NULL) < 0)
+		err(-1, "newconn kevent");
+
+	started++;
+	return (conn);
+}
+
+static void
+tcpp_client_closeconn(struct connection *conn)
+{
+
+	close(conn->conn_fd);
+	bzero(conn, sizeof(*conn));
+	free(conn);
+	finished++;
+}
+
+static void
+tcpp_client_handleconn(struct kevent *kev)
+{
+	struct connection *conn;
+	struct iovec iov[2];
+	ssize_t len, header_left;
+
+	conn = kev->udata;
+	if (conn->conn_magic != CONNECTION_MAGIC)
+		errx(-1, "tcpp_client_handleconn: magic");
+
+	if (conn->conn_header_sent < sizeof(conn->conn_header)) {
+		header_left = sizeof(conn->conn_header) -
+		    conn->conn_header_sent;
+		iov[0].iov_base = ((u_char *)&conn->conn_header) +
+		    conn->conn_header_sent;
+		iov[0].iov_len = header_left;
+		iov[1].iov_base = buffer;
+		iov[1].iov_len = min(sizeof(buffer), payload_len);
+		len = writev(conn->conn_fd, iov, 2);
+		if (len < 0) {
+			tcpp_client_closeconn(conn);
+			err(-1, "tcpp_client_handleconn: header write");
+		}
+		if (len == 0) {
+			tcpp_client_closeconn(conn);
+			errx(-1, "tcpp_client_handleconn: header write "
+			    "premature EOF");
+		}
+		if (len > header_left) {
+			conn->conn_data_sent += (len - header_left);
+			conn->conn_header_sent += header_left;
+		} else
+			conn->conn_header_sent += len;
+	} else {
+		len = write(conn->conn_fd, buffer, min(sizeof(buffer),
+		    payload_len - conn->conn_data_sent));
+		if (len < 0) {
+			tcpp_client_closeconn(conn);
+			err(-1, "tcpp_client_handleconn: data write");
+		}
+		if (len == 0) {
+			tcpp_client_closeconn(conn);
+			errx(-1, "tcpp_client_handleconn: data write: "
+			    "premature EOF");
+		}
+		conn->conn_data_sent += len;
+	}
+	if (conn->conn_data_sent >= payload_len) {
+		/*
+		 * All is well.
+		 */
+		tcpp_client_closeconn(conn);
+	}
+}
+
+static void
+tcpp_client_worker(int workernum)
+{
+	struct kevent *kev_array;
+	int i, numevents, kev_bytes;
+#if defined(CPU_SETSIZE) && 0
+	cpu_set_t mask;
+	int ncpus;
+	size_t len;
+
+	if (Pflag) {
+		len = sizeof(ncpus);
+		if (sysctlbyname(SYSCTLNAME_CPUS, &ncpus, &len, NULL, 0) < 0)
+			err(-1, "sysctlbyname: %s", SYSCTLNAME_CPUS);
+		if (len != sizeof(ncpus))
+			errx(-1, "sysctlbyname: %s: len %jd", SYSCTLNAME_CPUS,
+			    (intmax_t)len);
+
+		CPU_ZERO(&mask);
+		CPU_SET(workernum % ncpus, &mask);
+		if (sched_setaffinity(0, CPU_SETSIZE, &mask) < 0)
+			err(-1, "sched_setaffinity");
+	}
+#endif
+	setproctitle("tcpp_client %d", workernum);
+
+	/*
+	 * Add the worker number to the remote port.
+	 */
+	remoteip.sin_port = htons(rflag + workernum);
+
+	kev_bytes = sizeof(*kev_array) * mflag;
+	kev_array = malloc(kev_bytes);
+	if (kev_array == NULL)
+		err(-1, "malloc");
+	bzero(kev_array, kev_bytes);
+
+	kq = kqueue();
+	if (kq < 0)
+		err(-1, "kqueue");
+
+	while (finished < tflag) {
+		while ((started - finished < mflag) && (started < tflag))
+			(void)tcpp_client_newconn();
+		numevents = kevent(kq, NULL, 0, kev_array, mflag, NULL);
+		if (numevents < 0)
+			err(-1, "kevent");
+		if (numevents > mflag)
+			errx(-1, "kevent: %d", numevents);
+		for (i = 0; i < numevents; i++)
+			tcpp_client_handleconn(&kev_array[i]);
+	}
+	/* printf("Worker %d done - %d finished\n", workernum, finished); */
+}
+
+void
+tcpp_client(void)
+{
+	struct timespec ts_start, ts_finish;
+	long cp_time_start[CPUSTATES], cp_time_finish[CPUSTATES];
+	long ticks;
+	size_t size;
+	pid_t pid;
+	int i, failed, status;
+
+	if (bflag < sizeof(struct tcpp_header))
+		errx(-1, "Can't use -b less than %zu\n",
+		   sizeof(struct tcpp_header));
+	payload_len = bflag - sizeof(struct tcpp_header);
+
+	pid_list = malloc(sizeof(*pid_list) * pflag);
+	if (pid_list == NULL)
+		err(-1, "malloc pid_list");
+	bzero(pid_list, sizeof(*pid_list) * pflag);
+
+	/*
+	 * Start workers.
+	 */
+	size = sizeof(cp_time_start);
+	if (sysctlbyname(SYSCTLNAME_CPTIME, &cp_time_start, &size, NULL, 0)
+	    < 0)
+		err(-1, "sysctlbyname: %s", SYSCTLNAME_CPTIME);
+	if (clock_gettime(CLOCK_REALTIME, &ts_start) < 0)
+		err(-1, "clock_gettime");
+	for (i = 0; i < pflag; i++) {
+		pid = fork();
+		if (pid < 0) {
+			warn("fork");
+			for (i = 0; i < pflag; i++) {
+				if (pid_list[i] != 0)
+					(void)kill(pid_list[i], SIGKILL);
+			}
+			exit(-1);
+		}
+		if (pid == 0) {
+			tcpp_client_worker(i);
+			exit(0);
+		}
+		pid_list[i] = pid;
+	}
+
+	/*
+	 * GC workers.
+	 */
+	failed = 0;
+	for (i = 0; i < pflag; i++) {
+		if (pid_list[i] != 0) {
+			while (waitpid(pid_list[i], &status, 0) != pid_list[i]);
+			if (WEXITSTATUS(status) != 0)
+				failed = 1;
+		}
+	}
+	if (clock_gettime(CLOCK_REALTIME, &ts_finish) < 0)
+		err(-1, "clock_gettime");
+	size = sizeof(cp_time_finish);
+	if (sysctlbyname(SYSCTLNAME_CPTIME, &cp_time_finish, &size, NULL, 0)
+	    < 0)
+		err(-1, "sysctlbyname: %s", SYSCTLNAME_CPTIME);
+	timespecsub(&ts_finish, &ts_start);
+
+	if (failed)
+		errx(-1, "Too many errors");
+
+	if (hflag)
+		printf("bytes,seconds,conn/s,Gb/s,user%%,nice%%,sys%%,"
+		    "intr%%,idle%%\n");
+
+	/*
+	 * Configuration parameters.
+	 */
+	printf("%jd,", bflag * tflag * pflag);
+	printf("%jd.%09jd,", (intmax_t)ts_finish.tv_sec,
+	    (intmax_t)(ts_finish.tv_nsec));
+
+	/*
+	 * Effective transmit rates.
+	 */
+	printf("%f,", (double)(pflag * tflag)/
+	    (ts_finish.tv_sec + ts_finish.tv_nsec * 1e-9));
+	printf("%f,", (double)(bflag * tflag * pflag * 8) /
+	    (ts_finish.tv_sec + ts_finish.tv_nsec * 1e-9) * 1e-9);
+
+	/*
+	 * CPU time (est).
+	 */
+	ticks = 0;
+	for (i = 0; i < CPUSTATES; i++) {
+		cp_time_finish[i] -= cp_time_start[i];
+		ticks += cp_time_finish[i];
+	}
+	printf("%0.02f,", (float)(100 * cp_time_finish[CP_USER]) / ticks);
+	printf("%0.02f,", (float)(100 * cp_time_finish[CP_NICE]) / ticks);
+	printf("%0.02f,", (float)(100 * cp_time_finish[CP_SYS]) / ticks);
+	printf("%0.02f,", (float)(100 * cp_time_finish[CP_INTR]) / ticks);
+	printf("%0.02f", (float)(100 * cp_time_finish[CP_IDLE]) / ticks);
+	printf("\n");
+}


Property changes on: trunk/tools/tools/netrate/tcpp/tcpp_client.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/tools/tools/netrate/tcpp/tcpp_server.c
===================================================================
--- trunk/tools/tools/netrate/tcpp/tcpp_server.c	                        (rev 0)
+++ trunk/tools/tools/netrate/tcpp/tcpp_server.c	2018-07-21 20:03:50 UTC (rev 11941)
@@ -0,0 +1,350 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2008-2009 Robert N. M. Watson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD: stable/10/tools/tools/netrate/tcpp/tcpp_server.c 208873 2010-06-06 15:27:08Z rwatson $
+ */
+
+#include <sys/types.h>
+#include <sys/endian.h>
+#include <sys/event.h>
+#include <sys/resource.h>
+#include <sys/sched.h>
+#include <sys/socket.h>
+#include <sys/sysctl.h>
+#include <sys/time.h>
+#include <sys/wait.h>
+
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+
+#include <err.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "tcpp.h"
+
+/*
+ * Server side -- create a pool of processes, each listening on its own TCP
+ * port number for new connections.  The first 8 bytes of each connection
+ * will be a network byte order length, then there will be that number of
+ * bytes of data.  We use non-blocking sockets with kqueue to to avoid the
+ * overhead of threading or more than one process per processor, which makes
+ * things a bit awkward when dealing with data we care about.  As such, we
+ * read into a small character buffer which we then convert to a length once
+ * we have all the data.
+ */
+#define	CONNECTION_MAGIC	0x6392af27
+struct connection {
+	uint32_t	conn_magic;		/* Just magic. */
+	int		conn_fd;
+	struct tcpp_header	conn_header;	/* Header buffer. */
+	u_int		conn_header_len;	/* Bytes so far. */
+	u_int64_t	conn_data_len;		/* How much to sink. */
+	u_int64_t	conn_data_received;	/* How much so far. */
+};
+
+static pid_t			*pid_list;
+static int			 kq;
+
+static struct connection *
+tcpp_server_newconn(int listen_fd)
+{
+	struct connection *conn;
+	struct kevent kev;
+	int fd;
+
+	fd = accept(listen_fd, NULL, NULL);
+	if (fd < 0) {
+		warn("accept");
+		return (NULL);
+	}
+
+	if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0)
+		err(-1, "fcntl");
+
+	conn = malloc(sizeof(*conn));
+	if (conn == NULL)
+		return (NULL);
+	bzero(conn, sizeof(*conn));
+	conn->conn_magic = CONNECTION_MAGIC;
+	conn->conn_fd = fd;
+
+	/*
+	 * Register to read on the socket, and set our conn pointer as the
+	 * udata so we can find it quickly in the future.
+	 */
+	EV_SET(&kev, fd, EVFILT_READ, EV_ADD, 0, 0, conn);
+	if (kevent(kq, &kev, 1, NULL, 0, NULL) < 0)
+		err(-1, "kevent");
+
+	return (conn);
+}
+
+static void
+tcpp_server_closeconn(struct connection *conn)
+{
+
+	/*
+	 * Kqueue cleans up after itself once we close the socket, and since
+	 * we are processing only one kevent at a time, we don't need to
+	 * worry about watching out for future kevents referring to it.
+	 *
+	 * ... right?
+	 */
+	close(conn->conn_fd);
+	bzero(conn, sizeof(*conn));
+	free(conn);
+}
+
+static u_char buffer[256*1024];	/* Buffer in which to sink data. */
+static void
+tcpp_server_handleconn(struct kevent *kev)
+{
+	struct connection *conn;
+	ssize_t len;
+
+	conn = kev->udata;
+	if (conn->conn_magic != CONNECTION_MAGIC)
+		errx(-1, "tcpp_server_handleconn: magic");
+
+	if (conn->conn_header_len < sizeof(conn->conn_header)) {
+		len = read(conn->conn_fd,
+		    ((u_char *)&conn->conn_header) + conn->conn_header_len,
+		    sizeof(conn->conn_header) - conn->conn_header_len);
+		if (len < 0) {
+			warn("tcpp_server_handleconn: header read");
+			tcpp_server_closeconn(conn);
+			return;
+		}
+		if (len == 0) {
+			warnx("tcpp_server_handleconn: header premature eof");
+			tcpp_server_closeconn(conn);
+			return;
+		}
+		conn->conn_header_len += len;
+		if (conn->conn_header_len == sizeof(conn->conn_header)) {
+			tcpp_header_decode(&conn->conn_header);
+			if (conn->conn_header.th_magic != TCPP_MAGIC) {
+				warnx("tcpp_server_handleconn: bad magic");
+				tcpp_server_closeconn(conn);
+				return;
+			}
+		}
+	} else {
+		/*
+		 * Drain up to a buffer from the connection, so that we pay
+		 * attention to other connections too.
+		 */
+		len = read(conn->conn_fd, buffer, sizeof(buffer));
+		if (len < 0) {
+			warn("tcpp_server_handleconn: data bad read");
+			tcpp_server_closeconn(conn);
+			return;
+		}
+		if (len == 0 && conn->conn_data_received <
+		    conn->conn_header.th_len) {
+			warnx("tcpp_server_handleconn: data premature eof");
+			tcpp_server_closeconn(conn);
+			return;
+		}
+		conn->conn_data_received += len;
+		if (conn->conn_data_received > conn->conn_header.th_len) {
+			warnx("tcpp_server_handleconn: too much data");
+			tcpp_server_closeconn(conn);
+			return;
+		}
+		if (conn->conn_data_received == conn->conn_header.th_len) {
+			/*
+			 * All is well.
+			 */
+			tcpp_server_closeconn(conn);
+			return;
+		}
+	}
+}
+
+static void
+tcpp_server_worker(int workernum)
+{
+	int i, listen_sock, numevents;
+	struct kevent kev, *kev_array;
+	int kev_bytes;
+#if defined(CPU_SETSIZE) && 0
+	cpu_set_t mask;
+	int ncpus;
+	ssize_t len;
+
+	if (Pflag) {
+		len = sizeof(ncpus);
+		if (sysctlbyname(SYSCTLNAME_CPUS, &ncpus, &len, NULL, 0) < 0)
+			err(-1, "sysctlbyname: %s", SYSCTLNAME_CPUS);
+		if (len != sizeof(ncpus))
+			errx(-1, "sysctlbyname: %s: len %jd", SYSCTLNAME_CPUS,
+			    (intmax_t)len);
+
+		CPU_ZERO(&mask);
+		CPU_SET(workernum % ncpus, &mask);
+		if (sched_setaffinity(0, CPU_SETSIZE, &mask) < 0)
+			err(-1, "sched_setaffinity");
+	}
+#endif
+	setproctitle("tcpp_server %d", workernum);
+
+	/* Allow an extra kevent for the listen socket. */
+	kev_bytes = sizeof(*kev_array) * (mflag + 1);
+	kev_array = malloc(kev_bytes);
+	if (kev_array == NULL)
+		err(-1, "malloc");
+	bzero(kev_array, kev_bytes);
+
+	/* XXXRW: Want to set and pin the CPU here. */
+
+	/*
+	 * Add the worker number to the local port.
+	 */
+	localipbase.sin_port = htons(rflag + workernum);
+
+	listen_sock = socket(PF_INET, SOCK_STREAM, 0);
+	if (listen_sock < 0)
+		err(-1, "socket");
+	i = 1;
+	if (setsockopt(listen_sock, SOL_SOCKET, SO_NOSIGPIPE, &i, sizeof(i))
+	    < 0)
+		err(-1, "setsockopt");
+	i = 1;
+	if (setsockopt(listen_sock, SOL_SOCKET, SO_REUSEPORT, &i, sizeof(i))
+	    < 0)
+		err(-1, "setsockopt");
+	i = 1;
+	if (setsockopt(listen_sock, IPPROTO_TCP, TCP_NODELAY, &i, sizeof(i))
+	    < 0)
+		err(-1, "setsockopt");
+	if (bind(listen_sock, (struct sockaddr *)&localipbase,
+	    sizeof(localipbase)) < 0)
+		err(-1, "bind");
+	if (listen(listen_sock, 16384))
+		err(-1, "listen");
+	if (fcntl(listen_sock, F_SETFL, O_NONBLOCK) < 0)
+		err(-1, "fcntl");
+
+	kq = kqueue();
+	if (kq < 0)
+		err(-1, "kqueue");
+
+	EV_SET(&kev, listen_sock, EVFILT_READ, EV_ADD, 0, 0, NULL);
+	if (kevent(kq, &kev, 1, NULL, 0, NULL) < 0)
+		err(-1, "kevent");
+
+	while ((numevents = kevent(kq, NULL, 0, kev_array, mflag + 1, NULL))
+	    > 0) {
+		for (i = 0; i < numevents; i++) {
+			if (kev_array[i].ident == (u_int)listen_sock)
+				(void)tcpp_server_newconn(listen_sock);
+			else
+				tcpp_server_handleconn(&kev_array[i]);
+		}
+	}
+	printf("Worker %d done\n", workernum);
+}
+
+void
+tcpp_server(void)
+{
+#if 0
+	long cp_time_last[CPUSTATES], cp_time_now[CPUSTATES], ticks;
+	size_t size;
+#endif
+	pid_t pid;
+	int i;
+
+	pid_list = malloc(sizeof(*pid_list) * pflag);
+	if (pid_list == NULL)
+		err(-1, "malloc pid_list");
+	bzero(pid_list, sizeof(*pid_list) * pflag);
+
+	/*
+	 * Start workers.
+	 */
+	for (i = 0; i < pflag; i++) {
+		pid = fork();
+		if (pid < 0) {
+			warn("fork");
+			for (i = 0; i < pflag; i++) {
+				if (pid_list[i] != 0)
+					(void)kill(pid_list[i], SIGKILL);
+			}
+			exit(-1);
+		}
+		if (pid == 0) {
+			tcpp_server_worker(i);
+			exit(0);
+		}
+		pid_list[i] = pid;
+	}
+
+#if 0
+		size = sizeof(cp_time_last);
+		if (sysctlbyname(SYSCTLNAME_CPTIME, &cp_time_last, &size,
+		    NULL, 0) < 0)
+			err(-1, "sysctlbyname: %s", SYSCTLNAME_CPTIME);
+		while (1) {
+			sleep(10);
+			size = sizeof(cp_time_last);
+			if (sysctlbyname(SYSCTLNAME_CPTIME, &cp_time_now,
+			    &size, NULL, 0) < 0)
+				err(-1, "sysctlbyname: %s",
+				    SYSCTLNAME_CPTIME);
+			ticks = 0;
+			for (i = 0; i < CPUSTATES; i++) {
+				cp_time_last[i] = cp_time_now[i] -
+				    cp_time_last[i];
+				ticks += cp_time_last[i];
+			}
+			printf("user%% %lu nice%% %lu sys%% %lu intr%% %lu "
+			    "idle%% %lu\n",
+			    (100 * cp_time_last[CP_USER]) / ticks,
+			    (100 * cp_time_last[CP_NICE]) / ticks,
+			    (100 * cp_time_last[CP_SYS]) / ticks,
+			    (100 * cp_time_last[CP_INTR]) / ticks,
+			    (100 * cp_time_last[CP_IDLE]) / ticks);
+			bcopy(cp_time_now, cp_time_last, sizeof(cp_time_last));
+		}
+#endif
+
+	/*
+	 * GC workers.
+	 */
+	for (i = 0; i < pflag; i++) {
+		if (pid_list[i] != 0) {
+			while (waitpid(pid_list[i], NULL, 0) != pid_list[i]);
+		}
+	}
+}


Property changes on: trunk/tools/tools/netrate/tcpp/tcpp_server.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/tools/tools/netrate/tcpp/tcpp_util.c
===================================================================
--- trunk/tools/tools/netrate/tcpp/tcpp_util.c	                        (rev 0)
+++ trunk/tools/tools/netrate/tcpp/tcpp_util.c	2018-07-21 20:03:50 UTC (rev 11941)
@@ -0,0 +1,49 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2008 Robert N. M. Watson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD: stable/10/tools/tools/netrate/tcpp/tcpp_util.c 189623 2009-03-10 14:52:17Z rwatson $
+ */
+
+#include <sys/types.h>
+#include <sys/endian.h>
+
+#include "tcpp.h"
+
+void
+tcpp_header_encode(struct tcpp_header *thp)
+{
+
+	thp->th_magic = htobe32(thp->th_magic);
+	thp->th_len = htobe64(thp->th_len);
+}
+
+void
+tcpp_header_decode(struct tcpp_header *thp)
+{
+
+	thp->th_magic = be32toh(thp->th_magic);
+	thp->th_len = be64toh(thp->th_len);
+}


Property changes on: trunk/tools/tools/netrate/tcpp/tcpp_util.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property


More information about the Midnightbsd-cvs mailing list