Page MenuHomeFreeBSD

D21324.id61001.diff
No OneTemporary

D21324.id61001.diff

Index: contrib/netcat/nc.1
===================================================================
--- contrib/netcat/nc.1
+++ contrib/netcat/nc.1
@@ -27,7 +27,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd September 26, 2015
+.Dd August 20, 2019
.Dt NC 1
.Os
.Sh NAME
@@ -36,7 +36,7 @@
.Sh SYNOPSIS
.Nm nc
.Bk -words
-.Op Fl 46DdEFhklNnrStUuvz
+.Op Fl 46DdEFhklMNnrStUuvz
.Op Fl e Ar IPsec_policy
.Op Fl I Ar length
.Op Fl i Ar interval
@@ -170,6 +170,12 @@
Additionally, any timeouts specified with the
.Fl w
option are ignored.
+.It Fl M
+Collect per-connection TCP statistics using the
+.Xr stats 3
+framework and dump then in JSON format to
+.Xr stderr 4
+after the connection is closed.
.It Fl N
.Xr shutdown 2
the network socket after EOF on the input.
Index: contrib/netcat/netcat.c
===================================================================
--- contrib/netcat/netcat.c
+++ contrib/netcat/netcat.c
@@ -33,10 +33,29 @@
* *Hobbit* <hobbit@avian.org>.
*/
+#include <err.h>
+#include <errno.h>
+#include <getopt.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <netdb.h>
+#include <poll.h>
+#include <signal.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include "atomicio.h"
+
#include <sys/limits.h>
#include <sys/types.h>
+#include <sys/tree.h>
+#include <sys/sbuf.h>
#include <sys/socket.h>
#include <sys/sysctl.h>
+#include <sys/qmath.h>
+#include <sys/stats.h>
#include <sys/time.h>
#include <sys/uio.h>
#include <sys/un.h>
@@ -49,20 +68,6 @@
#include <netinet/ip.h>
#include <arpa/telnet.h>
-#include <err.h>
-#include <errno.h>
-#include <getopt.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <netdb.h>
-#include <poll.h>
-#include <signal.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include "atomicio.h"
#ifndef SUN_LEN
#define SUN_LEN(su) \
@@ -85,6 +90,7 @@
unsigned int iflag; /* Interval Flag */
int kflag; /* More than one connect */
int lflag; /* Bind to local port */
+int FreeBSD_Mflag; /* Measure using stats(3) */
int Nflag; /* shutdown() network socket */
int nflag; /* Don't do name look up */
int FreeBSD_Oflag; /* Do not use TCP options */
@@ -123,6 +129,7 @@
int unix_bind(char *);
int unix_connect(char *);
int unix_listen(char *);
+void print_measurements(int);
void set_common_sockopts(int, int);
int map_tos(char *, int *);
void report_connect(const struct sockaddr *, socklen_t);
@@ -167,7 +174,7 @@
signal(SIGPIPE, SIG_IGN);
while ((ch = getopt_long(argc, argv,
- "46DdEe:FhI:i:klNnoO:P:p:rSs:tT:UuV:vw:X:x:z",
+ "46DdEe:FhI:i:klMNnoO:P:p:rSs:tT:UuV:vw:X:x:z",
longopts, NULL)) != -1) {
switch (ch) {
case '4':
@@ -224,6 +231,9 @@
case 'l':
lflag = 1;
break;
+ case 'M':
+ FreeBSD_Mflag = 1;
+ break;
case 'N':
Nflag = 1;
break;
@@ -827,17 +837,23 @@
/* both inputs are gone, buffers are empty, we are done */
if (pfd[POLL_STDIN].fd == -1 && pfd[POLL_NETIN].fd == -1
&& stdinbufpos == 0 && netinbufpos == 0) {
+ if (FreeBSD_Mflag)
+ print_measurements(net_fd);
close(net_fd);
return;
}
/* both outputs are gone, we can't continue */
if (pfd[POLL_NETOUT].fd == -1 && pfd[POLL_STDOUT].fd == -1) {
+ if (FreeBSD_Mflag)
+ print_measurements(net_fd);
close(net_fd);
return;
}
/* listen and net in gone, queues empty, done */
if (lflag && pfd[POLL_NETIN].fd == -1
&& stdinbufpos == 0 && netinbufpos == 0) {
+ if (FreeBSD_Mflag)
+ print_measurements(net_fd);
close(net_fd);
return;
}
@@ -1181,6 +1197,46 @@
}
void
+print_measurements(int s)
+{
+ struct statsblob *sb;
+ struct sbuf *sbuf;
+ socklen_t sockoptlen;
+ int error;
+
+ sockoptlen = 2048;
+ sb = (struct statsblob *)malloc(sockoptlen);
+ if (sb == NULL)
+ err(1, "malloc");
+ error = getsockopt(s, IPPROTO_TCP, TCP_STATS, sb, &sockoptlen);
+ if (error != 0) {
+ if (errno == EOVERFLOW && sb->cursz > sockoptlen) {
+ /* Retry with a larger size. */
+ sockoptlen = sb->cursz;
+ sb = realloc(sb, sockoptlen);
+ if (sb == NULL)
+ errno = ENOMEM;
+ else
+ error = getsockopt(s, IPPROTO_TCP, TCP_STATS,
+ sb, &sockoptlen);
+ }
+ if (error != 0)
+ err(1, "getsockopt");
+ }
+
+ sbuf = sbuf_new_auto();
+ error = stats_blob_tostr(sb, sbuf, SB_STRFMT_JSON, SB_TOSTR_META);
+ if (error != 0)
+ err(1, "stats_blob_tostr");
+
+ error = sbuf_finish(sbuf);
+ if (error != 0)
+ err(1, "sbuf_finish");
+
+ fprintf(stderr, "%s\n", sbuf_data(sbuf));
+}
+
+void
set_common_sockopts(int s, int af)
{
int x = 1;
@@ -1218,6 +1274,11 @@
if (setsockopt(s, SOL_SOCKET, SO_SNDBUF,
&Oflag, sizeof(Oflag)) == -1)
err(1, "set TCP send buffer size");
+ }
+ if (FreeBSD_Mflag) {
+ if (setsockopt(s, IPPROTO_TCP, TCP_STATS,
+ &FreeBSD_Mflag, sizeof(FreeBSD_Mflag)) == -1)
+ err(1, "enable TCP_STATS gathering");
}
if (FreeBSD_Oflag) {
if (setsockopt(s, IPPROTO_TCP, TCP_NOOPT,
Index: usr.bin/nc/Makefile
===================================================================
--- usr.bin/nc/Makefile
+++ usr.bin/nc/Makefile
@@ -6,7 +6,7 @@
SRCS= netcat.c atomicio.c socks.c
CFLAGS+=-DIPSEC
-LIBADD= ipsec
+LIBADD= ipsec sbuf stats
WARNS?= 2

File Metadata

Mime Type
text/plain
Expires
Sun, Nov 16, 12:24 AM (17 h, 36 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
25345712
Default Alt Text
D21324.id61001.diff (5 KB)

Event Timeline