introduce-test-ping-app.patch
Signed-off-by: Andy Green <andy@warmcat.com>
This commit is contained in:
parent
f1d2113d6e
commit
a6cbece1ac
12 changed files with 653 additions and 10 deletions
|
@ -37,6 +37,11 @@ There are a couple of other possible configure options
|
|||
look for trust certificates to validate
|
||||
the remote certificate against.
|
||||
|
||||
--enable-noping Don't try to build the ping test app
|
||||
It needs some unixy environment that
|
||||
may choke in other build contexts, this
|
||||
lets you cleanly stop it being built
|
||||
|
||||
Testing server with a browser
|
||||
-----------------------------
|
||||
|
||||
|
@ -107,6 +112,53 @@ use_ssl var being set to 2. Set it to 1 to reject any server
|
|||
certificate that it doesn't have a trusted CA cert for.
|
||||
|
||||
|
||||
Using the websocket ping utility
|
||||
--------------------------------
|
||||
|
||||
libwebsockets-test-ping connects as a client to a remote
|
||||
websocket server using 04 protocol and pings it like the
|
||||
normal unix ping utility.
|
||||
|
||||
$ libwebsockets-test-ping localhost
|
||||
handshake OK for protocol lws-mirror-protocol
|
||||
Websocket PING localhost.localdomain (127.0.0.1) 64 bytes of data.
|
||||
64 bytes from localhost: req=1 time=0.1ms
|
||||
64 bytes from localhost: req=2 time=0.1ms
|
||||
64 bytes from localhost: req=3 time=0.1ms
|
||||
64 bytes from localhost: req=4 time=0.2ms
|
||||
64 bytes from localhost: req=5 time=0.1ms
|
||||
64 bytes from localhost: req=6 time=0.2ms
|
||||
64 bytes from localhost: req=7 time=0.2ms
|
||||
64 bytes from localhost: req=8 time=0.1ms
|
||||
^C
|
||||
--- localhost.localdomain websocket ping statistics ---
|
||||
8 packets transmitted, 8 received, 0% packet loss, time 7458ms
|
||||
rtt min/avg/max = 0.110/0.185/0.218 ms
|
||||
$
|
||||
|
||||
By default it sends 64 byte payload packets using the 04
|
||||
PING packet opcode type. You can change the payload size
|
||||
using the -s= flag, up to a maximum of 125 mandated by the
|
||||
04 standard.
|
||||
|
||||
Using the lws-mirror protocol that is provided by the test
|
||||
server, libwebsockets-test-ping can also use larger payload
|
||||
sizes up to 4096 is BINARY packets; lws-mirror will copy
|
||||
them back to the client and they appear as a PONG. Use the
|
||||
-m flag to select this operation.
|
||||
|
||||
The default interval between pings is 1s, you can use the -i=
|
||||
flag to set this, including fractions like -i=0.01 for 10ms
|
||||
interval.
|
||||
|
||||
Before you can even use the PING opcode that is part of the
|
||||
standard, you must complete a handshake with a specified
|
||||
protocol. By default lws-mirror-protocol is used which is
|
||||
supported by the test server. But if you are using it on
|
||||
another server, you can specify the protcol to handshake with
|
||||
by --protocol=protocolname
|
||||
|
||||
|
||||
Websocket version supported
|
||||
---------------------------
|
||||
|
||||
|
|
28
configure
vendored
28
configure
vendored
|
@ -616,6 +616,8 @@ ac_subst_vars='am__EXEEXT_FALSE
|
|||
am__EXEEXT_TRUE
|
||||
LTLIBOBJS
|
||||
LIBOBJS
|
||||
NOPING_FALSE
|
||||
NOPING_TRUE
|
||||
clientcertdir
|
||||
LIBCRYPTO_FALSE
|
||||
LIBCRYPTO_TRUE
|
||||
|
@ -741,6 +743,7 @@ enable_openssl
|
|||
enable_nofork
|
||||
enable_libcrypto
|
||||
with_client_cert_dir
|
||||
enable_noping
|
||||
'
|
||||
ac_precious_vars='build_alias
|
||||
host_alias
|
||||
|
@ -1386,6 +1389,7 @@ Optional Features:
|
|||
--enable-openssl Enables https support and needs openssl libs
|
||||
--enable-nofork Disables fork-related options
|
||||
--enable-libcrypto Use libcrypto MD5 and SHA1 implementations
|
||||
--enable-noping Do not build ping test app, which has some unixy stuff in sources
|
||||
|
||||
Optional Packages:
|
||||
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
|
||||
|
@ -12307,6 +12311,26 @@ fi
|
|||
|
||||
|
||||
|
||||
#
|
||||
#
|
||||
#
|
||||
# Check whether --enable-noping was given.
|
||||
if test "${enable_noping+set}" = set; then :
|
||||
enableval=$enable_noping; noping=yes
|
||||
|
||||
fi
|
||||
|
||||
|
||||
if test x$noping = xyes; then
|
||||
NOPING_TRUE=
|
||||
NOPING_FALSE='#'
|
||||
else
|
||||
NOPING_TRUE='#'
|
||||
NOPING_FALSE=
|
||||
fi
|
||||
|
||||
|
||||
|
||||
|
||||
# Checks for header files.
|
||||
for ac_header in fcntl.h netinet/in.h stdlib.h string.h sys/socket.h unistd.h
|
||||
|
@ -12621,6 +12645,10 @@ if test -z "${LIBCRYPTO_TRUE}" && test -z "${LIBCRYPTO_FALSE}"; then
|
|||
as_fn_error $? "conditional \"LIBCRYPTO\" was never defined.
|
||||
Usually this means the macro was only invoked conditionally." "$LINENO" 5
|
||||
fi
|
||||
if test -z "${NOPING_TRUE}" && test -z "${NOPING_FALSE}"; then
|
||||
as_fn_error $? "conditional \"NOPING\" was never defined.
|
||||
Usually this means the macro was only invoked conditionally." "$LINENO" 5
|
||||
fi
|
||||
|
||||
: "${CONFIG_STATUS=./config.status}"
|
||||
ac_write_fail=0
|
||||
|
|
11
configure.ac
11
configure.ac
|
@ -73,6 +73,17 @@ AC_SUBST([clientcertdir])
|
|||
AC_SUBST([CFLAGS])
|
||||
|
||||
|
||||
#
|
||||
#
|
||||
#
|
||||
AC_ARG_ENABLE(noping,
|
||||
[ --enable-noping Do not build ping test app, which has some unixy stuff in sources],
|
||||
[ noping=yes
|
||||
])
|
||||
|
||||
AM_CONDITIONAL(NOPING, test x$noping = xyes)
|
||||
|
||||
|
||||
|
||||
# Checks for header files.
|
||||
AC_CHECK_HEADERS([fcntl.h netinet/in.h stdlib.h string.h sys/socket.h unistd.h])
|
||||
|
|
|
@ -514,6 +514,21 @@ libwebsocket_callback_on_writable_all_protocol(
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* libwebsocket_get_socket_fd() - returns the socket file descriptor
|
||||
*
|
||||
* You will not need this unless you are doing something special
|
||||
*
|
||||
* @wsi: Websocket connection instance
|
||||
*/
|
||||
|
||||
int
|
||||
libwebsocket_get_socket_fd(struct libwebsocket *wsi)
|
||||
{
|
||||
return wsi->sock;
|
||||
}
|
||||
|
||||
/**
|
||||
* libwebsocket_rx_flow_control() - Enable and disable socket servicing for
|
||||
* receieved packets.
|
||||
|
|
|
@ -30,6 +30,7 @@ enum libwebsocket_callback_reasons {
|
|||
LWS_CALLBACK_CLOSED,
|
||||
LWS_CALLBACK_RECEIVE,
|
||||
LWS_CALLBACK_CLIENT_RECEIVE,
|
||||
LWS_CALLBACK_CLIENT_RECEIVE_PONG,
|
||||
LWS_CALLBACK_CLIENT_WRITEABLE,
|
||||
LWS_CALLBACK_HTTP,
|
||||
LWS_CALLBACK_BROADCAST
|
||||
|
@ -87,6 +88,10 @@ struct libwebsocket_context;
|
|||
* remote client, it can be found at *in and is
|
||||
* len bytes long
|
||||
*
|
||||
* LWS_CALLBACK_CLIENT_RECEIVE_PONG: if you elected to see PONG packets,
|
||||
* they appear with this callback reason. PONG
|
||||
* packets only exist in 04+ protocol
|
||||
*
|
||||
* LWS_CALLBACK_CLIENT_RECEIVE: data has appeared from the server for the
|
||||
* client connection, it can be found at *in and
|
||||
* is len bytes long
|
||||
|
@ -225,6 +230,8 @@ extern int
|
|||
libwebsocket_callback_on_writable_all_protocol(
|
||||
const struct libwebsocket_protocols *protocol);
|
||||
|
||||
extern int
|
||||
libwebsocket_get_socket_fd(struct libwebsocket *wsi);
|
||||
|
||||
extern int
|
||||
libwebsocket_rx_flow_control(struct libwebsocket *wsi, int enable);
|
||||
|
|
|
@ -560,7 +560,9 @@ spill:
|
|||
n = libwebsocket_write(wsi, (unsigned char *)
|
||||
&wsi->rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING],
|
||||
wsi->rx_user_buffer_head, LWS_WRITE_PONG);
|
||||
break;
|
||||
/* ... then just drop it */
|
||||
wsi->rx_user_buffer_head = 0;
|
||||
return 0;
|
||||
|
||||
case LWS_WS_OPCODE_04__PONG:
|
||||
/* keep the statistics... */
|
||||
|
@ -599,6 +601,7 @@ int libwebsocket_client_rx_sm(struct libwebsocket *wsi, unsigned char c)
|
|||
{
|
||||
int n;
|
||||
unsigned char buf[20 + 4];
|
||||
int callback_action = LWS_CALLBACK_CLIENT_RECEIVE;
|
||||
|
||||
switch (wsi->lws_rx_parse_state) {
|
||||
case LWS_RXPS_NEW:
|
||||
|
@ -875,9 +878,10 @@ spill:
|
|||
case LWS_WS_OPCODE_04__PONG:
|
||||
/* keep the statistics... */
|
||||
wsi->pings_vs_pongs--;
|
||||
/* ... then just drop it */
|
||||
wsi->rx_user_buffer_head = 0;
|
||||
return 0;
|
||||
|
||||
/* issue it */
|
||||
callback_action = LWS_CALLBACK_CLIENT_RECEIVE_PONG;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
|
@ -890,8 +894,7 @@ spill:
|
|||
*/
|
||||
|
||||
if (wsi->protocol->callback)
|
||||
wsi->protocol->callback(wsi,
|
||||
LWS_CALLBACK_CLIENT_RECEIVE,
|
||||
wsi->protocol->callback(wsi, callback_action,
|
||||
wsi->user_space,
|
||||
&wsi->rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING],
|
||||
wsi->rx_user_buffer_head);
|
||||
|
|
|
@ -73,7 +73,7 @@ static inline void debug(const char *format, ...)
|
|||
#define LWS_MAX_HEADER_LEN 4096
|
||||
#define LWS_INITIAL_HDR_ALLOC 256
|
||||
#define LWS_ADDITIONAL_HDR_ALLOC 64
|
||||
#define MAX_USER_RX_BUFFER 512
|
||||
#define MAX_USER_RX_BUFFER 4096
|
||||
#define MAX_BROADCAST_PAYLOAD 2048
|
||||
#define LWS_MAX_PROTOCOLS 10
|
||||
|
||||
|
|
|
@ -78,6 +78,21 @@ nothing is pending, or as soon as it services whatever was pending.
|
|||
<dd>Protocol whose connections will get callbacks
|
||||
</dl>
|
||||
<hr>
|
||||
<h2>libwebsocket_get_socket_fd - returns the socket file descriptor</h2>
|
||||
<i>int</i>
|
||||
<b>libwebsocket_get_socket_fd</b>
|
||||
(<i>struct libwebsocket *</i> <b>wsi</b>)
|
||||
<h3>Arguments</h3>
|
||||
<dl>
|
||||
<dt><b>wsi</b>
|
||||
<dd>Websocket connection instance
|
||||
</dl>
|
||||
<h3>Description</h3>
|
||||
<blockquote>
|
||||
<p>
|
||||
You will not need this unless you are doing something special
|
||||
</blockquote>
|
||||
<hr>
|
||||
<h2>libwebsocket_rx_flow_control - Enable and disable socket servicing for receieved packets.</h2>
|
||||
<i>int</i>
|
||||
<b>libwebsocket_rx_flow_control</b>
|
||||
|
@ -394,6 +409,12 @@ data has appeared for this server endpoint from a
|
|||
remote client, it can be found at *in and is
|
||||
len bytes long
|
||||
</blockquote>
|
||||
<h3>LWS_CALLBACK_CLIENT_RECEIVE_PONG</h3>
|
||||
<blockquote>
|
||||
if you elected to see PONG packets,
|
||||
they appear with this callback reason. PONG
|
||||
packets only exist in 04+ protocol
|
||||
</blockquote>
|
||||
<h3>LWS_CALLBACK_CLIENT_RECEIVE</h3>
|
||||
<blockquote>
|
||||
data has appeared from the server for the
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
Name: libwebsockets
|
||||
Version: 0.1
|
||||
Release: 44.gmaster_f55830db%{?dist}
|
||||
Release: 45.gmaster_f1d2113d%{?dist}
|
||||
Summary: Websocket Server Library
|
||||
|
||||
Group: System
|
||||
|
@ -50,6 +50,7 @@ rm -rf $RPM_BUILD_ROOT
|
|||
/%{_libdir}/libwebsockets.la
|
||||
%attr(755,root,root) /usr/share/libwebsockets-test-server
|
||||
%attr(755,root,root) /usr/share/libwebsockets-test-client
|
||||
%attr(755,root,root) /usr/share/libwebsockets-test-ping
|
||||
%doc
|
||||
%files devel
|
||||
%defattr(-,root,root,-)
|
||||
|
|
|
@ -5,10 +5,18 @@ libwebsockets_test_client_SOURCES=test-client.c
|
|||
libwebsockets_test_client_LDADD=-L../lib -lwebsockets
|
||||
|
||||
|
||||
|
||||
libwebsockets_test_server_CFLAGS:= -Wall -Werror -std=gnu99 -pedantic -DDATADIR=\"@datadir@\" -DLWS_OPENSSL_CLIENT_CERTS=\"@clientcertdir@\"
|
||||
libwebsockets_test_client_CFLAGS:= -Wall -Werror -std=gnu99 -pedantic -DDATADIR=\"@datadir@\" -DLWS_OPENSSL_CLIENT_CERTS=\"@clientcertdir@\"
|
||||
|
||||
if NOPING
|
||||
else
|
||||
bin_PROGRAMS+=libwebsockets-test-ping
|
||||
libwebsockets_test_ping_SOURCES=test-ping.c
|
||||
libwebsockets_test_ping_LDADD=-L../lib -lwebsockets
|
||||
libwebsockets_test_ping_CFLAGS:= -Wall -Werror -std=gnu99 -pedantic -DDATADIR=\"@datadir@\" -DLWS_OPENSSL_CLIENT_CERTS=\"@clientcertdir@\"
|
||||
endif
|
||||
|
||||
|
||||
#
|
||||
# cook a random test cert and key
|
||||
# notice your real cert and key will want to be 0600 permissions
|
||||
|
|
|
@ -35,7 +35,8 @@ POST_UNINSTALL = :
|
|||
build_triplet = @build@
|
||||
host_triplet = @host@
|
||||
bin_PROGRAMS = libwebsockets-test-server$(EXEEXT) \
|
||||
libwebsockets-test-client$(EXEEXT)
|
||||
libwebsockets-test-client$(EXEEXT) $(am__EXEEXT_1)
|
||||
@NOPING_FALSE@am__append_1 = libwebsockets-test-ping
|
||||
subdir = test-server
|
||||
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
|
||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||
|
@ -46,6 +47,7 @@ mkinstalldirs = $(install_sh) -d
|
|||
CONFIG_HEADER = $(top_builddir)/config.h
|
||||
CONFIG_CLEAN_FILES =
|
||||
CONFIG_CLEAN_VPATH_FILES =
|
||||
@NOPING_FALSE@am__EXEEXT_1 = libwebsockets-test-ping$(EXEEXT)
|
||||
am__installdirs = "$(DESTDIR)$(bindir)"
|
||||
PROGRAMS = $(bin_PROGRAMS)
|
||||
am_libwebsockets_test_client_OBJECTS = \
|
||||
|
@ -57,6 +59,16 @@ libwebsockets_test_client_LINK = $(LIBTOOL) --tag=CC \
|
|||
$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
|
||||
$(libwebsockets_test_client_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
|
||||
$(LDFLAGS) -o $@
|
||||
am__libwebsockets_test_ping_SOURCES_DIST = test-ping.c
|
||||
@NOPING_FALSE@am_libwebsockets_test_ping_OBJECTS = \
|
||||
@NOPING_FALSE@ libwebsockets_test_ping-test-ping.$(OBJEXT)
|
||||
libwebsockets_test_ping_OBJECTS = \
|
||||
$(am_libwebsockets_test_ping_OBJECTS)
|
||||
libwebsockets_test_ping_DEPENDENCIES =
|
||||
libwebsockets_test_ping_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
|
||||
$(LIBTOOLFLAGS) --mode=link $(CCLD) \
|
||||
$(libwebsockets_test_ping_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
|
||||
$(LDFLAGS) -o $@
|
||||
am_libwebsockets_test_server_OBJECTS = \
|
||||
libwebsockets_test_server-test-server.$(OBJEXT)
|
||||
libwebsockets_test_server_OBJECTS = \
|
||||
|
@ -80,8 +92,10 @@ LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
|
|||
--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
|
||||
$(LDFLAGS) -o $@
|
||||
SOURCES = $(libwebsockets_test_client_SOURCES) \
|
||||
$(libwebsockets_test_ping_SOURCES) \
|
||||
$(libwebsockets_test_server_SOURCES)
|
||||
DIST_SOURCES = $(libwebsockets_test_client_SOURCES) \
|
||||
$(am__libwebsockets_test_ping_SOURCES_DIST) \
|
||||
$(libwebsockets_test_server_SOURCES)
|
||||
ETAGS = etags
|
||||
CTAGS = ctags
|
||||
|
@ -206,6 +220,9 @@ libwebsockets_test_client_SOURCES = test-client.c
|
|||
libwebsockets_test_client_LDADD = -L../lib -lwebsockets
|
||||
libwebsockets_test_server_CFLAGS := -Wall -Werror -std=gnu99 -pedantic -DDATADIR=\"@datadir@\" -DLWS_OPENSSL_CLIENT_CERTS=\"@clientcertdir@\"
|
||||
libwebsockets_test_client_CFLAGS := -Wall -Werror -std=gnu99 -pedantic -DDATADIR=\"@datadir@\" -DLWS_OPENSSL_CLIENT_CERTS=\"@clientcertdir@\"
|
||||
@NOPING_FALSE@libwebsockets_test_ping_SOURCES = test-ping.c
|
||||
@NOPING_FALSE@libwebsockets_test_ping_LDADD = -L../lib -lwebsockets
|
||||
@NOPING_FALSE@libwebsockets_test_ping_CFLAGS := -Wall -Werror -std=gnu99 -pedantic -DDATADIR=\"@datadir@\" -DLWS_OPENSSL_CLIENT_CERTS=\"@clientcertdir@\"
|
||||
all: all-am
|
||||
|
||||
.SUFFIXES:
|
||||
|
@ -286,6 +303,9 @@ clean-binPROGRAMS:
|
|||
libwebsockets-test-client$(EXEEXT): $(libwebsockets_test_client_OBJECTS) $(libwebsockets_test_client_DEPENDENCIES)
|
||||
@rm -f libwebsockets-test-client$(EXEEXT)
|
||||
$(libwebsockets_test_client_LINK) $(libwebsockets_test_client_OBJECTS) $(libwebsockets_test_client_LDADD) $(LIBS)
|
||||
libwebsockets-test-ping$(EXEEXT): $(libwebsockets_test_ping_OBJECTS) $(libwebsockets_test_ping_DEPENDENCIES)
|
||||
@rm -f libwebsockets-test-ping$(EXEEXT)
|
||||
$(libwebsockets_test_ping_LINK) $(libwebsockets_test_ping_OBJECTS) $(libwebsockets_test_ping_LDADD) $(LIBS)
|
||||
libwebsockets-test-server$(EXEEXT): $(libwebsockets_test_server_OBJECTS) $(libwebsockets_test_server_DEPENDENCIES)
|
||||
@rm -f libwebsockets-test-server$(EXEEXT)
|
||||
$(libwebsockets_test_server_LINK) $(libwebsockets_test_server_OBJECTS) $(libwebsockets_test_server_LDADD) $(LIBS)
|
||||
|
@ -297,6 +317,7 @@ distclean-compile:
|
|||
-rm -f *.tab.c
|
||||
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebsockets_test_client-test-client.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebsockets_test_ping-test-ping.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebsockets_test_server-test-server.Po@am__quote@
|
||||
|
||||
.c.o:
|
||||
|
@ -334,6 +355,20 @@ libwebsockets_test_client-test-client.obj: test-client.c
|
|||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwebsockets_test_client_CFLAGS) $(CFLAGS) -c -o libwebsockets_test_client-test-client.obj `if test -f 'test-client.c'; then $(CYGPATH_W) 'test-client.c'; else $(CYGPATH_W) '$(srcdir)/test-client.c'; fi`
|
||||
|
||||
libwebsockets_test_ping-test-ping.o: test-ping.c
|
||||
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwebsockets_test_ping_CFLAGS) $(CFLAGS) -MT libwebsockets_test_ping-test-ping.o -MD -MP -MF $(DEPDIR)/libwebsockets_test_ping-test-ping.Tpo -c -o libwebsockets_test_ping-test-ping.o `test -f 'test-ping.c' || echo '$(srcdir)/'`test-ping.c
|
||||
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libwebsockets_test_ping-test-ping.Tpo $(DEPDIR)/libwebsockets_test_ping-test-ping.Po
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test-ping.c' object='libwebsockets_test_ping-test-ping.o' libtool=no @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwebsockets_test_ping_CFLAGS) $(CFLAGS) -c -o libwebsockets_test_ping-test-ping.o `test -f 'test-ping.c' || echo '$(srcdir)/'`test-ping.c
|
||||
|
||||
libwebsockets_test_ping-test-ping.obj: test-ping.c
|
||||
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwebsockets_test_ping_CFLAGS) $(CFLAGS) -MT libwebsockets_test_ping-test-ping.obj -MD -MP -MF $(DEPDIR)/libwebsockets_test_ping-test-ping.Tpo -c -o libwebsockets_test_ping-test-ping.obj `if test -f 'test-ping.c'; then $(CYGPATH_W) 'test-ping.c'; else $(CYGPATH_W) '$(srcdir)/test-ping.c'; fi`
|
||||
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libwebsockets_test_ping-test-ping.Tpo $(DEPDIR)/libwebsockets_test_ping-test-ping.Po
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test-ping.c' object='libwebsockets_test_ping-test-ping.obj' libtool=no @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwebsockets_test_ping_CFLAGS) $(CFLAGS) -c -o libwebsockets_test_ping-test-ping.obj `if test -f 'test-ping.c'; then $(CYGPATH_W) 'test-ping.c'; else $(CYGPATH_W) '$(srcdir)/test-ping.c'; fi`
|
||||
|
||||
libwebsockets_test_server-test-server.o: test-server.c
|
||||
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwebsockets_test_server_CFLAGS) $(CFLAGS) -MT libwebsockets_test_server-test-server.o -MD -MP -MF $(DEPDIR)/libwebsockets_test_server-test-server.Tpo -c -o libwebsockets_test_server-test-server.o `test -f 'test-server.c' || echo '$(srcdir)/'`test-server.c
|
||||
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libwebsockets_test_server-test-server.Tpo $(DEPDIR)/libwebsockets_test_server-test-server.Po
|
||||
|
|
462
test-server/test-ping.c
Normal file
462
test-server/test-ping.c
Normal file
|
@ -0,0 +1,462 @@
|
|||
/*
|
||||
* libwebsockets-test-ping - libwebsockets floodping
|
||||
*
|
||||
* Copyright (C) 2011 Andy Green <andy@warmcat.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation:
|
||||
* version 2.1 of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <getopt.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include "../lib/libwebsockets.h"
|
||||
#include <poll.h>
|
||||
|
||||
/*
|
||||
* this is specified in the 04 standard, control frames can only have small
|
||||
* payload length styles
|
||||
*/
|
||||
#define MAX_PING_PAYLOAD 125
|
||||
#define MAX_MIRROR_PAYLOAD 4096
|
||||
|
||||
static unsigned int interval_us = 1000000;
|
||||
static unsigned int size = 64;
|
||||
static int flood = 0;
|
||||
static const char *address;
|
||||
static unsigned char pingbuf[LWS_SEND_BUFFER_PRE_PADDING + MAX_MIRROR_PAYLOAD +
|
||||
LWS_SEND_BUFFER_POST_PADDING];
|
||||
static unsigned long oldus = 0;
|
||||
static unsigned long ping_index = 1;
|
||||
static char *hname = "(unknown)";
|
||||
static unsigned long rx_count = 0;
|
||||
static unsigned long started;
|
||||
|
||||
static unsigned long rtt_min = 100000000;
|
||||
static unsigned long rtt_max = 0;
|
||||
static unsigned long rtt_avg = 0;
|
||||
static int screen_width = 80;
|
||||
static int use_mirror = 0;
|
||||
|
||||
struct ping {
|
||||
unsigned long issue_timestamp;
|
||||
unsigned long index;
|
||||
unsigned int seen;
|
||||
};
|
||||
|
||||
#define PING_RINGBUFFER_SIZE 256
|
||||
|
||||
struct ping ringbuffer[PING_RINGBUFFER_SIZE];
|
||||
int ringbuffer_head;
|
||||
int ringbuffer_tail;
|
||||
|
||||
/*
|
||||
* uses the ping pong protocol features to provide an equivalent for the
|
||||
* ping utility for 04+ websockets
|
||||
*/
|
||||
|
||||
enum demo_protocols {
|
||||
|
||||
PROTOCOL_LWS_MIRROR,
|
||||
|
||||
/* always last */
|
||||
DEMO_PROTOCOL_COUNT
|
||||
};
|
||||
|
||||
|
||||
static int
|
||||
callback_lws_mirror(struct libwebsocket *wsi,
|
||||
enum libwebsocket_callback_reasons reason,
|
||||
void *user, void *in, size_t len)
|
||||
{
|
||||
struct timeval tv;
|
||||
unsigned char *p;
|
||||
int shift;
|
||||
unsigned long l;
|
||||
unsigned long iv;
|
||||
int n;
|
||||
int match = 0;
|
||||
|
||||
switch (reason) {
|
||||
case LWS_CALLBACK_CLIENT_ESTABLISHED:
|
||||
|
||||
/*
|
||||
* start the ball rolling,
|
||||
* LWS_CALLBACK_CLIENT_WRITEABLE will come next service
|
||||
*/
|
||||
|
||||
libwebsocket_callback_on_writable(wsi);
|
||||
break;
|
||||
|
||||
case LWS_CALLBACK_CLIENT_RECEIVE:
|
||||
case LWS_CALLBACK_CLIENT_RECEIVE_PONG:
|
||||
gettimeofday(&tv, NULL);
|
||||
iv = (tv.tv_sec * 1000000) + tv.tv_usec;
|
||||
|
||||
rx_count++;
|
||||
|
||||
shift = 56;
|
||||
p = in;
|
||||
l = 0;
|
||||
|
||||
while (shift >= 0) {
|
||||
l |= (*p++) << shift;
|
||||
shift -= 8;
|
||||
}
|
||||
|
||||
/* find it in the ringbuffer, look backwards from head */
|
||||
n = ringbuffer_head;
|
||||
while (!match) {
|
||||
|
||||
if (ringbuffer[n].index == l) {
|
||||
ringbuffer[n].seen++;
|
||||
match = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (n == ringbuffer_tail) {
|
||||
match = -1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (n == 0)
|
||||
n = PING_RINGBUFFER_SIZE - 1;
|
||||
else
|
||||
n--;
|
||||
}
|
||||
|
||||
if (match < 1) {
|
||||
|
||||
if (!flood)
|
||||
fprintf(stderr, "%d bytes from %s: req=%ld "
|
||||
"time=(unknown)\n", (int)len, address, l);
|
||||
else
|
||||
fprintf(stderr, "\b \b");
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (ringbuffer[n].seen > 1)
|
||||
fprintf(stderr, "DUP! ");
|
||||
|
||||
if ((iv - ringbuffer[n].issue_timestamp) < rtt_min)
|
||||
rtt_min = iv - ringbuffer[n].issue_timestamp;
|
||||
|
||||
if ((iv - ringbuffer[n].issue_timestamp) > rtt_max)
|
||||
rtt_max = iv - ringbuffer[n].issue_timestamp;
|
||||
|
||||
rtt_avg += iv - ringbuffer[n].issue_timestamp;
|
||||
|
||||
|
||||
if (!flood)
|
||||
fprintf(stderr, "%d bytes from %s: req=%ld "
|
||||
"time=%lu.%lums\n", (int)len, address, l,
|
||||
(iv - ringbuffer[n].issue_timestamp) / 1000,
|
||||
((iv - ringbuffer[n].issue_timestamp) / 100) % 10
|
||||
);
|
||||
else
|
||||
fprintf(stderr, "\b \b");
|
||||
break;
|
||||
|
||||
case LWS_CALLBACK_CLIENT_WRITEABLE:
|
||||
|
||||
shift = 56;
|
||||
p = &pingbuf[LWS_SEND_BUFFER_PRE_PADDING];
|
||||
|
||||
while (shift >= 0) {
|
||||
*p++ = ping_index >> shift;
|
||||
shift -= 8;
|
||||
}
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
|
||||
ringbuffer[ringbuffer_head].issue_timestamp =
|
||||
(tv.tv_sec * 1000000) + tv.tv_usec;
|
||||
ringbuffer[ringbuffer_head].index = ping_index++;
|
||||
ringbuffer[ringbuffer_head].seen = 0;
|
||||
|
||||
if (ringbuffer_head == PING_RINGBUFFER_SIZE - 1)
|
||||
ringbuffer_head = 0;
|
||||
else
|
||||
ringbuffer_head++;
|
||||
|
||||
/* snip any re-used tail so we keep the whole buffer length */
|
||||
|
||||
if (ringbuffer_tail == ringbuffer_head) {
|
||||
if (ringbuffer_tail == PING_RINGBUFFER_SIZE - 1)
|
||||
ringbuffer_tail = 0;
|
||||
else
|
||||
ringbuffer_tail++;
|
||||
}
|
||||
|
||||
if (use_mirror)
|
||||
libwebsocket_write(wsi,
|
||||
&pingbuf[LWS_SEND_BUFFER_PRE_PADDING],
|
||||
size, LWS_WRITE_BINARY);
|
||||
else
|
||||
libwebsocket_write(wsi,
|
||||
&pingbuf[LWS_SEND_BUFFER_PRE_PADDING],
|
||||
size, LWS_WRITE_PING);
|
||||
|
||||
if (flood && (ping_index - rx_count) < (screen_width - 1))
|
||||
fprintf(stderr, ".");
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* list of supported protocols and callbacks */
|
||||
|
||||
static struct libwebsocket_protocols protocols[] = {
|
||||
|
||||
[PROTOCOL_LWS_MIRROR] = {
|
||||
.name = "lws-mirror-protocol",
|
||||
.callback = callback_lws_mirror,
|
||||
},
|
||||
[DEMO_PROTOCOL_COUNT] = { /* end of list */
|
||||
.callback = NULL
|
||||
}
|
||||
};
|
||||
|
||||
static struct option options[] = {
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "port", required_argument, NULL, 'p' },
|
||||
{ "ssl", no_argument, NULL, 't' },
|
||||
{ "interval", required_argument, NULL, 'i' },
|
||||
{ "size", required_argument, NULL, 's' },
|
||||
{ "protocol", required_argument, NULL, 'n' },
|
||||
{ "flood", no_argument, NULL, 'f' },
|
||||
{ "mirror", no_argument, NULL, 'm' },
|
||||
{ NULL, 0, 0, 0 }
|
||||
};
|
||||
|
||||
|
||||
static void
|
||||
signal_handler(int sig, siginfo_t *si, void *v)
|
||||
{
|
||||
struct timeval tv;
|
||||
unsigned long l;
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
l = (tv.tv_sec * 1000000) + tv.tv_usec;
|
||||
|
||||
fprintf(stderr, "\n--- %s websocket ping statistics ---\n"
|
||||
"%lu packets transmitted, %lu received, %lu%% packet loss, time %ldms\n"
|
||||
"rtt min/avg/max = %0.3f/%0.3f/%0.3f ms\n",
|
||||
hname, ping_index - 1, rx_count,
|
||||
(((ping_index - 1) - rx_count) * 100) / (ping_index - 1),
|
||||
(l - started) / 1000,
|
||||
((double)rtt_min) / 1000.0,
|
||||
((double)rtt_avg / rx_count) / 1000.0,
|
||||
((double)rtt_max) / 1000.0
|
||||
);
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int n = 0;
|
||||
int port = 7681;
|
||||
int use_ssl = 0;
|
||||
struct libwebsocket_context *context;
|
||||
struct libwebsocket *wsi_mirror;
|
||||
char protocol_name[256];
|
||||
unsigned int len;
|
||||
struct sockaddr_in sin;
|
||||
struct hostent *host;
|
||||
struct hostent *host1;
|
||||
char ip[30];
|
||||
char *p;
|
||||
struct sigaction sa;
|
||||
struct timeval tv;
|
||||
struct winsize w;
|
||||
|
||||
if (argc < 2)
|
||||
goto usage;
|
||||
|
||||
address = argv[1];
|
||||
optind++;
|
||||
|
||||
while (n >= 0) {
|
||||
n = getopt_long(argc, argv, "hmfts:n:i:p:", options, NULL);
|
||||
if (n < 0)
|
||||
continue;
|
||||
switch (n) {
|
||||
case 'm':
|
||||
use_mirror = 1;
|
||||
break;
|
||||
case 't':
|
||||
use_ssl = 2; /* 2 = allow selfsigned */
|
||||
break;
|
||||
case 'p':
|
||||
port = atoi(optarg);
|
||||
break;
|
||||
case 'n':
|
||||
strncpy(protocol_name, optarg, sizeof protocol_name);
|
||||
protocol_name[(sizeof protocol_name) -1] = '\0';
|
||||
protocols[PROTOCOL_LWS_MIRROR].name = protocol_name;
|
||||
break;
|
||||
case 'i':
|
||||
interval_us = 1000000.0 * atof(optarg);
|
||||
break;
|
||||
case 's':
|
||||
size = atoi(optarg);
|
||||
break;
|
||||
case 'f':
|
||||
flood = 1;
|
||||
break;
|
||||
case 'h':
|
||||
goto usage;
|
||||
}
|
||||
}
|
||||
|
||||
if (!use_mirror) {
|
||||
if (size > MAX_PING_PAYLOAD) {
|
||||
fprintf(stderr, "Max ping opcode payload size %d\n",
|
||||
MAX_PING_PAYLOAD);
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
if (size > MAX_MIRROR_PAYLOAD) {
|
||||
fprintf(stderr, "Max mirror payload size %d\n",
|
||||
MAX_MIRROR_PAYLOAD);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (isatty(STDOUT_FILENO))
|
||||
if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &w) != -1)
|
||||
if (w.ws_col > 0)
|
||||
screen_width = w.ws_col;
|
||||
|
||||
context = libwebsocket_create_context(CONTEXT_PORT_NO_LISTEN,
|
||||
protocols, NULL, NULL, -1, -1);
|
||||
if (context == NULL) {
|
||||
fprintf(stderr, "Creating libwebsocket context failed\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* create a client websocket using dumb increment protocol */
|
||||
|
||||
wsi_mirror = libwebsocket_client_connect(context, address, port, use_ssl,
|
||||
"/", "http://host", "origin",
|
||||
protocols[PROTOCOL_LWS_MIRROR].name);
|
||||
|
||||
if (wsi_mirror == NULL) {
|
||||
fprintf(stderr, "libwebsocket connect failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
strcpy(ip, "(unknown)");
|
||||
len = sizeof sin;
|
||||
if (getpeername(libwebsocket_get_socket_fd(wsi_mirror),
|
||||
(struct sockaddr *) &sin, &len) < 0)
|
||||
perror("getpeername");
|
||||
else {
|
||||
host = gethostbyaddr((char *) &sin.sin_addr,
|
||||
sizeof sin.sin_addr,
|
||||
AF_INET);
|
||||
if (host == NULL)
|
||||
perror("gethostbyaddr");
|
||||
else {
|
||||
hname = host->h_name;
|
||||
|
||||
host1 = gethostbyname(hname);
|
||||
if (host1 != NULL) {
|
||||
p = (char *)host1;
|
||||
n = 0;
|
||||
while (p != NULL) {
|
||||
p = host1->h_addr_list[n++];
|
||||
if (p == NULL)
|
||||
continue;
|
||||
if (host1->h_addrtype != AF_INET)
|
||||
continue;
|
||||
|
||||
sprintf(ip, "%d.%d.%d.%d",
|
||||
p[0], p[1], p[2], p[3]);
|
||||
p = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(stderr, "Websocket PING %s (%s) %d bytes of data.\n",
|
||||
hname, ip, size);
|
||||
|
||||
/* set the ^C handler */
|
||||
|
||||
sa.sa_sigaction = signal_handler;
|
||||
sa.sa_flags = SA_SIGINFO;
|
||||
sigemptyset(&sa.sa_mask);
|
||||
sigaction(SIGINT, &sa, NULL);
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
started = (tv.tv_sec * 1000000) + tv.tv_usec;
|
||||
|
||||
/* service loop */
|
||||
|
||||
n = 0;
|
||||
while (n >= 0) {
|
||||
unsigned long l;
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
|
||||
l = (tv.tv_sec * 1000000) + tv.tv_usec;
|
||||
if ((l - oldus) > interval_us) {
|
||||
libwebsocket_callback_on_writable(wsi_mirror);
|
||||
oldus = l;
|
||||
}
|
||||
|
||||
if (!interval_us)
|
||||
n = libwebsocket_service(context, 0);
|
||||
else
|
||||
n = libwebsocket_service(context, 1);
|
||||
}
|
||||
|
||||
libwebsocket_client_close(wsi_mirror);
|
||||
libwebsocket_context_destroy(context);
|
||||
|
||||
return 0;
|
||||
|
||||
usage:
|
||||
fprintf(stderr, "Usage: libwebsockets-test-ping "
|
||||
"<server address> [--port=<p>] "
|
||||
"[--ssl] [--interval=<float sec>] "
|
||||
"[--size=<bytes>] "
|
||||
"[--protocol=<protocolname>] "
|
||||
"[--mirror] "
|
||||
"\n");
|
||||
return 1;
|
||||
}
|
Loading…
Add table
Reference in a new issue