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 DATADIR"/libwebsockets-test-server"
42 /* fraggle protocol */
44 struct per_session_data__fraggle {
52 callback_fraggle(struct libwebsocket_context * context,
53 struct libwebsocket *wsi,
54 enum libwebsocket_callback_reasons reason,
55 void *user, void *in, size_t len)
58 unsigned char buf[LWS_SEND_BUFFER_PRE_PADDING + 2048 +
59 LWS_SEND_BUFFER_POST_PADDING];
60 struct per_session_data__fraggle *psf = user;
62 int write_mode = LWS_WRITE_CONTINUATION;
64 unsigned char *p = (unsigned char *)in;
68 case LWS_CALLBACK_ESTABLISHED:
69 fprintf(stderr, "server sees client connect\n");
70 psf->packets_left = -1;
71 /* start the ball rolling */
72 libwebsocket_callback_on_writable(context, wsi);
75 case LWS_CALLBACK_CLIENT_ESTABLISHED:
76 fprintf(stderr, "client connects to server\n");
77 /* next guy will be start of new message */
81 case LWS_CALLBACK_CLIENT_RECEIVE:
82 switch (psf->rx_state) {
89 fprintf(stderr, "EOM received %d correctly "
90 "from %d fragments\n",
91 psf->total_message, psf->packets_left);
93 fprintf(stderr, "**** ERROR at EOM: "
94 "length %d, rx sum = 0x%lX, "
95 "server says it sent 0x%lX\n",
96 psf->total_message, psf->sum, sum);
97 /* next guy will be start of new message */
101 /* expect the start of the message */
104 psf->total_message = 0;
105 psf->packets_left = 0;
110 for (n = 0; n < len; n++)
113 psf->total_message += len;
116 if (libwebsocket_is_final_fragment(wsi))
118 * next guy will be server's
126 case LWS_CALLBACK_SERVER_WRITEABLE:
128 if (psf->packets_left == 0) {
129 /* reached the end */
130 fprintf(stderr, "Spamming session over, "
131 "len = %d. sum = 0x%lX\n",
132 psf->total_message, psf->sum);
134 p[0] = psf->sum >> 24;
135 p[1] = psf->sum >> 16;
136 p[2] = psf->sum >> 8;
139 n = libwebsocket_write(wsi, (unsigned char *)p,
142 libwebsocket_callback_on_writable(context, wsi);
148 if (psf->packets_left < 1) {
149 /* start a new blob */
151 psf->packets_left = (random() % 1024) + 1;
152 fprintf(stderr, "Spamming %d random fragments\n",
155 psf->total_message = 0;
156 write_mode = LWS_WRITE_BINARY;
159 chunk = (random() % 2000) + 1;
160 psf->total_message += chunk;
162 libwebsockets_get_random(context,
163 &buf[LWS_SEND_BUFFER_PRE_PADDING], chunk);
164 for (n = 0; n < chunk; n++)
165 psf->sum += buf[LWS_SEND_BUFFER_PRE_PADDING + n];
168 if (psf->packets_left)
169 write_mode |= LWS_WRITE_NO_FIN;
171 n = libwebsocket_write(wsi, (unsigned char *)
172 &buf[LWS_SEND_BUFFER_PRE_PADDING], chunk, write_mode);
174 libwebsocket_callback_on_writable(context, wsi);
178 /* because we are protocols[0] ... */
180 case LWS_CALLBACK_CLIENT_CONFIRM_EXTENSION_SUPPORTED:
181 if (strcmp(in, "deflate-stream") == 0)
182 fprintf(stderr, "denied deflate-stream extension\n");
195 /* list of supported protocols and callbacks */
197 static struct libwebsocket_protocols protocols[] = {
201 sizeof(struct per_session_data__fraggle),
204 NULL, NULL, 0 /* End of list */
208 static struct option options[] = {
209 { "help", no_argument, NULL, 'h' },
210 { "port", required_argument, NULL, 'p' },
211 { "ssl", no_argument, NULL, 's' },
212 { "killmask", no_argument, NULL, 'k' },
213 { "interface", required_argument, NULL, 'i' },
214 { "client", no_argument, NULL, 'c' },
218 int main(int argc, char **argv)
221 const char *cert_path =
222 LOCAL_RESOURCE_PATH"/libwebsockets-test-server.pem";
223 const char *key_path =
224 LOCAL_RESOURCE_PATH"/libwebsockets-test-server.key.pem";
227 struct libwebsocket_context *context;
229 char interface_name[128] = "";
230 const char * interface = NULL;
231 struct libwebsocket *wsi;
233 int server_port = port;
235 fprintf(stderr, "libwebsockets test fraggle\n"
236 "(C) Copyright 2010-2011 Andy Green <andy@warmcat.com> "
237 "licensed under LGPL2.1\n");
240 n = getopt_long(argc, argv, "ci:khsp:", options, NULL);
248 opts = LWS_SERVER_OPTION_DEFEAT_CLIENT_MASK;
255 strncpy(interface_name, optarg, sizeof interface_name);
256 interface_name[(sizeof interface_name) - 1] = '\0';
257 interface = interface_name;
261 fprintf(stderr, " Client mode\n");
264 fprintf(stderr, "Usage: test-server "
265 "[--port=<p>] [--ssl]\n");
271 server_port = CONTEXT_PORT_NO_LISTEN;
272 if (optind >= argc) {
273 fprintf(stderr, "Must give address of server\n");
279 cert_path = key_path = NULL;
281 context = libwebsocket_create_context(server_port, interface, protocols,
282 libwebsocket_internal_extensions,
283 cert_path, key_path, -1, -1, opts);
284 if (context == NULL) {
285 fprintf(stderr, "libwebsocket init failed\n");
290 address = argv[optind];
291 fprintf(stderr, "Connecting to %s:%u\n", address, port);
292 wsi = libwebsocket_client_connect(context, address,
293 port, use_ssl, "/", address,
294 "origin", protocols[PROTOCOL_FRAGGLE].name,
297 fprintf(stderr, "Client connect to server failed\n");
304 n = libwebsocket_service(context, 50);
307 libwebsocket_context_destroy(context);