2 * libwebsockets-test-fraggle - random fragmentation test
4 * Copyright (C) 2010-2011 Andy Green <andy@warmcat.com>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation:
9 * version 2.1 of the License.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
29 #include "../lib/libwebsockets.h"
31 #define LOCAL_RESOURCE_PATH INSTALL_DATADIR"/libwebsockets-test-server"
43 /* fraggle protocol */
46 FRAGSTATE_START_MESSAGE,
47 FRAGSTATE_RANDOM_PAYLOAD,
48 FRAGSTATE_POST_PAYLOAD_SUM,
51 struct per_session_data__fraggle {
55 enum fraggle_states state;
59 callback_fraggle(struct libwebsocket_context *context,
60 struct libwebsocket *wsi,
61 enum libwebsocket_callback_reasons reason,
62 void *user, void *in, size_t len)
65 unsigned char buf[LWS_SEND_BUFFER_PRE_PADDING + 2048 +
66 LWS_SEND_BUFFER_POST_PADDING];
67 struct per_session_data__fraggle *psf = user;
69 int write_mode = LWS_WRITE_CONTINUATION;
71 unsigned char *p = (unsigned char *)in;
72 unsigned char *bp = &buf[LWS_SEND_BUFFER_PRE_PADDING];
76 case LWS_CALLBACK_ESTABLISHED:
78 fprintf(stderr, "server sees client connect\n");
79 psf->state = FRAGSTATE_START_MESSAGE;
80 /* start the ball rolling */
81 libwebsocket_callback_on_writable(context, wsi);
84 case LWS_CALLBACK_CLIENT_ESTABLISHED:
86 fprintf(stderr, "client connects to server\n");
87 psf->state = FRAGSTATE_START_MESSAGE;
90 case LWS_CALLBACK_CLIENT_RECEIVE:
94 case FRAGSTATE_START_MESSAGE:
96 psf->state = FRAGSTATE_RANDOM_PAYLOAD;
98 psf->total_message = 0;
99 psf->packets_left = 0;
103 case FRAGSTATE_RANDOM_PAYLOAD:
105 for (n = 0; n < len; n++)
108 psf->total_message += len;
111 if (libwebsocket_is_final_fragment(wsi))
112 psf->state = FRAGSTATE_POST_PAYLOAD_SUM;
115 case FRAGSTATE_POST_PAYLOAD_SUM:
122 fprintf(stderr, "EOM received %d correctly "
123 "from %d fragments\n",
124 psf->total_message, psf->packets_left);
126 fprintf(stderr, "**** ERROR at EOM: "
127 "length %d, rx sum = 0x%lX, "
128 "server says it sent 0x%lX\n",
129 psf->total_message, psf->sum, sum);
131 psf->state = FRAGSTATE_START_MESSAGE;
136 case LWS_CALLBACK_SERVER_WRITEABLE:
138 switch (psf->state) {
140 case FRAGSTATE_START_MESSAGE:
142 psf->packets_left = (random() % 1024) + 1;
143 fprintf(stderr, "Spamming %d random fragments\n",
146 psf->total_message = 0;
147 write_mode = LWS_WRITE_BINARY;
148 psf->state = FRAGSTATE_RANDOM_PAYLOAD;
152 case FRAGSTATE_RANDOM_PAYLOAD:
154 chunk = (random() % 2000) + 1;
155 psf->total_message += chunk;
157 libwebsockets_get_random(context, bp, chunk);
158 for (n = 0; n < chunk; n++)
162 if (psf->packets_left)
163 write_mode |= LWS_WRITE_NO_FIN;
165 psf->state = FRAGSTATE_POST_PAYLOAD_SUM;
167 n = libwebsocket_write(wsi, bp, chunk, write_mode);
169 libwebsocket_callback_on_writable(context, wsi);
172 case FRAGSTATE_POST_PAYLOAD_SUM:
174 fprintf(stderr, "Spamming session over, "
175 "len = %d. sum = 0x%lX\n",
176 psf->total_message, psf->sum);
178 bp[0] = psf->sum >> 24;
179 bp[1] = psf->sum >> 16;
180 bp[2] = psf->sum >> 8;
183 n = libwebsocket_write(wsi, (unsigned char *)bp,
184 4, LWS_WRITE_BINARY);
186 psf->state = FRAGSTATE_START_MESSAGE;
188 libwebsocket_callback_on_writable(context, wsi);
193 case LWS_CALLBACK_CLOSED:
198 /* because we are protocols[0] ... */
200 case LWS_CALLBACK_CLIENT_CONFIRM_EXTENSION_SUPPORTED:
201 if (strcmp(in, "deflate-stream") == 0) {
202 fprintf(stderr, "denied deflate-stream extension\n");
216 /* list of supported protocols and callbacks */
218 static struct libwebsocket_protocols protocols[] = {
222 sizeof(struct per_session_data__fraggle),
225 NULL, NULL, 0 /* End of list */
229 static struct option options[] = {
230 { "help", no_argument, NULL, 'h' },
231 { "debug", required_argument, NULL, 'd' },
232 { "port", required_argument, NULL, 'p' },
233 { "ssl", no_argument, NULL, 's' },
234 { "interface", required_argument, NULL, 'i' },
235 { "client", no_argument, NULL, 'c' },
239 int main(int argc, char **argv)
242 const char *cert_path =
243 LOCAL_RESOURCE_PATH"/libwebsockets-test-server.pem";
244 const char *key_path =
245 LOCAL_RESOURCE_PATH"/libwebsockets-test-server.key.pem";
248 struct libwebsocket_context *context;
250 char interface_name[128] = "";
251 const char *interface = NULL;
252 struct libwebsocket *wsi;
254 int server_port = port;
256 fprintf(stderr, "libwebsockets test fraggle\n"
257 "(C) Copyright 2010-2013 Andy Green <andy@warmcat.com> "
258 "licensed under LGPL2.1\n");
261 n = getopt_long(argc, argv, "ci:hsp:d:", options, NULL);
266 lws_set_log_level(atoi(optarg), NULL);
276 strncpy(interface_name, optarg, sizeof interface_name);
277 interface_name[(sizeof interface_name) - 1] = '\0';
278 interface = interface_name;
282 fprintf(stderr, " Client mode\n");
285 fprintf(stderr, "Usage: libwebsockets-test-fraggle "
286 "[--port=<p>] [--ssl] "
287 "[-d <log bitfield>] "
294 server_port = CONTEXT_PORT_NO_LISTEN;
295 if (optind >= argc) {
296 fprintf(stderr, "Must give address of server\n");
302 cert_path = key_path = NULL;
304 context = libwebsocket_create_context(server_port, interface, protocols,
305 #ifndef LWS_NO_EXTENSIONS
306 libwebsocket_internal_extensions,
310 cert_path, key_path, NULL, -1, -1, opts, NULL);
311 if (context == NULL) {
312 fprintf(stderr, "libwebsocket init failed\n");
317 address = argv[optind];
318 fprintf(stderr, "Connecting to %s:%u\n", address, port);
319 wsi = libwebsocket_client_connect(context, address,
320 port, use_ssl, "/", address,
321 "origin", protocols[PROTOCOL_FRAGGLE].name,
324 fprintf(stderr, "Client connect to server failed\n");
330 while (!n && !terminate)
331 n = libwebsocket_service(context, 50);
333 fprintf(stderr, "Terminating...\n");
336 libwebsocket_context_destroy(context);