[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