123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968 |
- /*
- * fuzzing proxy - network-level fuzzing injection proxy
- *
- * Copyright (C) 2016 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
- *
- *
- * fuzxy is designed to go on the client path
- *
- * [ client <-> fuzxy ] <-> server
- *
- * you can arrange that with, eg,
- *
- * http_proxy=localhost:8880
- *
- * env var before starting the client.
- *
- * Even though he is on the client side, he is able to see and change traffic
- * in both directions, and so fuzz both the client and the server.
- */
- #if defined(_WIN32) && defined(EXTERNAL_POLL)
- #define WINVER 0x0600
- #define _WIN32_WINNT 0x0600
- #define poll(fdArray, fds, timeout) WSAPoll((LPWSAPOLLFD)(fdArray), (ULONG)(fds), (INT)(timeout))
- #endif
- #include "lws_config.h"
- #include <stdio.h>
- #include <stdlib.h>
- #include <getopt.h>
- #include <signal.h>
- #include <string.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <assert.h>
- #include <errno.h>
- #include "../lib/libwebsockets.h"
- #ifdef _WIN32
- #include <io.h>
- #include "gettimeofday.h"
- #else
- #include <syslog.h>
- #include <sys/time.h>
- #include <unistd.h>
- #include <sys/socket.h>
- #endif
- #if defined(__NetBSD__)
- #include <netinet/in.h>
- #endif
- #if defined(__sun)
- #include <strings.h> /* bzero */
- #endif
- #define MAX_FUZZ_BUF (1024 * 1024)
- enum types {
- FZY_S_DEAD = 0,
- FZY_S_LISTENING = 1,
- FZY_S_ACCEPTED = 2,
- FZY_S_PROXIED = 3,
- FZY_S_ONWARD = 4,
- };
- enum proxy_parser_states {
- FZY_PP_CONNECT = 0,
- FZY_PP_ADDRESS = 1,
- FZY_PP_PORT = 2,
- FZY_PP_CRLFS = 3,
- };
- enum fuzzer_parser_states {
- FZY_FP_SEARCH = 0,
- FZY_FP_SEARCH2 = 1,
- FZY_FP_INJECT_PREPARE = 2,
- FZY_FP_INJECT = 3,
- FZY_FP_PENDING = 4,
- };
- struct ring {
- char buf[4096];
- int head;
- int tail;
- };
- struct state {
- enum types type;
- enum proxy_parser_states pp;
- int ppc;
- struct ring in;
- char address[256];
- int port;
- enum fuzzer_parser_states fp;
- int fuzc;
- int pending;
- int twin; /* must be fixed up when arrays lose guys */
- unsigned int outbound:1; /* from local -> remote */
- unsigned int is_pending:1;
- unsigned char buf[MAX_FUZZ_BUF];
- unsigned int inject_len;
- };
- struct test {
- const char *s[3];
- int len[2];
- unsigned int swallow:1;
- };
- int force_exit = 0;
- int which = 5;
- static const struct test tests[] = {
- { { NULL, "\x0d\x0a\x0d\x0a",
- "{ 0xd9, 0x87, 0xd2, 0x88, 0xd2, (248){ 0x89, 0xd2 }, 0x0d, 0x0a },"
- }, { 0, 4 }, 1 },
- { { NULL, "\x0d\x0a\x0d\x0a",
- "{ 0xd9, 0x87, 0xd2, 0x88, 0xd2, (1373){ 0x89, 0xd2 }, 0x0d, 0x0a },"
- }, { 0, 4 }, 1 },
- { { NULL, "\x0d\x0a\x0d\x0a",
- "{ 0xd9, 0x87, 0xd2, 0x88, 0xd2, (16967){ 0x89, 0xd2 }, (87){ 0xe2, 0x82, 0xac }, 0x0d, 0x0a },"
- }, { 0, 4 }, 1 },
- { { NULL, "\x0d\x0a\x0d\x0a",
- "0x47, 0x45, 0x54, 0x20, 0x2f, 0x65, 0x63, 0x68, 0x6f, 0x20, 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, "
- "0x2e, 0x31, 0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20, 0x31, 0x32, 0x37, 0x2e, 0x30, 0x2e, "
- "0x30, 0x2e, 0x31, 0x0d, 0x0a, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x3a, 0x20, 0x77, 0x65, "
- "0x62, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, "
- "0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x0d, 0x0a, 0x53, 0x65, "
- "0x63, 0x2d, 0x57, 0x65, 0x62, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x2d, 0x4b, 0x65, 0x79, 0x3a, "
- "0x20, 0x64, 0x47, 0x68, 0x6c, 0x49, 0x48, 0x4e, 0x68, 0x62, 0x58, 0x42, 0x73, 0x5a, 0x53, 0x42, "
- "0x75, 0x62, 0x32, 0x35, 0x6a, 0x5a, 0x51, 0x3d, 0x3d, 0x0d, 0x0a, 0x4f, 0x72, 0x69, 0x67, 0x69, "
- "0x6e, 0x3a, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x31, 0x32, 0x37, 0x2e, 0x30, 0x2e, "
- "0x30, 0x2e, 0x31, 0x0d, 0x0a, 0x53, 0x65, 0x63, 0x2d, 0x57, 0x65, 0x62, 0x53, 0x6f, 0x63, 0x6b, "
- "0x65, 0x74, 0x2d, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x31, 0x33, 0x0d, 0x0a, "
- "0xef, 0xbb, 0xbf, 0xc2, 0x47, 0x45, 0x54, 0x20, 0x2f, 0x65, 0x63, 0x68, 0x6f, 0x20, 0x48, 0x54, "
- "0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31, 0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20, 0x31, 0x32, "
- "0x37, 0x2e, 0x30, 0x2e, 0x30, 0x2e, 0x31, 0x0d, 0x0a, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, "
- "0x3a, 0x20, 0x77, 0x65, 0x62, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, "
- "0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x0d, 0x0a, "
- }, { 0, 4 }, 1 },
- { { NULL, "\x0d\x0a\x0d\x0a",
- "(20){0x47, 0x45, 0x54, 0x20, 0x2f, 0x65, 0x63, 0x68, 0x6f, 0x20, 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, "
- "0x2e, 0x31, 0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20, 0x31, 0x32, 0x37, 0x2e, 0x30, 0x2e, "
- "0x30, 0x2e, 0x31, 0x0d, 0x0a, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x3a, 0x20, 0x77, 0x65, "
- "0x62, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, "
- "0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x0d, 0x0a, 0x53, 0x65, "
- "0x63, 0x2d, 0x57, 0x65, 0x62, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x2d, 0x4b, 0x65, 0x79, 0x3a, "
- "0x20, 0x64, 0x47, 0x68, 0x6c, 0x49, 0x48, 0x4e, 0x68, 0x62, 0x58, 0x42, 0x73, 0x5a, 0x53, 0x42, "
- "0x75, 0x62, 0x32, 0x35, 0x6a, 0x5a, 0x51, 0x3d, 0x3d, 0x0d, 0x0a, 0x4f, 0x72, 0x69, 0x67, 0x69, "
- "0x6e, 0x3a, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x31, 0x32, 0x37, 0x2e, 0x30, 0x2e, "
- "0x30, 0x2e, 0x31, 0x0d, 0x0a, 0x53, 0x65, 0x63, 0x2d, 0x57, 0x65, 0x62, 0x53, 0x6f, 0x63, 0x6b, "
- "0x65, 0x74, 0x2d, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x31, 0x33, 0x0d, 0x0a, "
- "0x47, 0x45, 0x54, 0x20, 0x2f, 0x65, 0x63, 0x68, 0x6f, 0x20, 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, "
- "0x2e, 0x31, 0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20, 0x31, 0x32, 0x37, 0x2e, 0x30, 0x2e, "
- "0x30, 0x2e, 0x31, 0x0d, 0x0a, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x3a, 0x20, 0x77, 0x65, "
- "0x62, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, "
- "0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x0d, 0x0a, 0x53, 0x65, "
- "0x63, 0x2d, 0x57, 0x65, 0x62, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x2d, 0x4b, 0x65, 0x79, 0x3a, "
- "0x20, 0x64, 0x47, 0x68, 0x6c, 0x49, 0x48, 0x4e, 0x68, 0x62, 0x58, 0x42, 0x73, 0x5a, 0x53, 0x42, "
- "0x75, 0x62, 0x32, 0x35, 0x6a, 0x5a, 0x51, 0x3d, 0x3d, 0x0d, 0x0a, 0x4f, 0x72, 0x69, 0x67, 0x69, "
- "0x6e, 0x3a, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x31, 0x32, 0x37, 0x2e, 0x30, 0x2e, "
- "0x30, 0x2e, 0x31, 0x0d, 0x0a, 0x53, 0x65, 0x63, 0x2d, 0x57, 0x65, 0x62, 0x53, 0x6f, 0x63, 0x6b, "
- "0x65, 0x74, 0x2d, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x31, 0x33, 0x0d, 0x0a, "
- "0xc2, 0x47, 0x45, 0x54, 0x20, 0x2f, 0x65, 0x63, 0x68, 0x6f, 0x20, 0x48, 0x54, 0x54, 0x50, 0x2f, "
- "0x31, 0x2e, 0x31, 0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20, 0x31, 0x32, 0x37, 0x2e, 0x30, "
- "0x2e, 0x30, 0x2e, 0x31, 0x0d, 0x0a, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x3a, 0x20, 0x77, "
- "0x65, 0x62, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, "
- "0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x0d, 0x0a, 0x53, "
- "0x65, 0x63, 0x2d, 0x57, 0x65, 0x62, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x2d, 0x4b, 0x65, 0x79, "
- "0x3a, 0x20, 0x64, 0x47, 0x68, 0x6c, 0x49, 0x48, 0x4e, 0x68, 0x62, 0x58, 0x42, 0x73, 0x5a, 0x53, "
- "0x42, 0x75, 0x62, 0x32, 0x35, 0x6a, 0x5a, 0x51, 0x3d, 0x3d, 0x0d, 0x0a, 0x4f, 0x72, 0x69, 0x67, "
- "0x69, 0x6e, 0x3a, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x31, 0x32, 0x37, 0x2e, 0x30, "
- "0x2e, 0x30, 0x2e, 0x31, 0x0d, 0x0a, 0x53, 0x65, 0x63, 0x2d, 0x57, 0x65, 0x62, 0x53, 0x6f, 0x63, "
- "0x6b, 0x65, 0x74, 0x2d, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x31, 0x33, 0x0d, "
- "0x0a, 0x47, 0x45, 0x54, 0x20, 0x2f, 0x65, 0x63, 0x68, 0x6f, 0x20, 0x48, 0x54, 0x54, 0x50, 0x2f, "
- "0x31, 0x2e, 0x31, 0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20, 0x31, 0x32, 0x37, 0x2e, 0x30, "
- "0x2e, 0x30, 0x2e, 0x31, 0x0d, 0x0a, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x3a, 0x20, 0x77, "
- "0x65, 0x62, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, "
- "0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x0d, 0x0a, 0x53, "
- "0x65, 0x63, 0x2d, 0x57, 0x65, 0x62, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x2d, 0x4b, 0x65, 0x79, "
- "0x3a, 0x20, 0x64, 0x47, 0x68, 0x6c, 0x49, 0x48, 0x4e, 0x68, 0x62, 0x58, 0x42, 0x73, 0x5a, 0x53, "
- "0x42, 0x75, 0x62, 0x32, 0x35, 0x6a, 0x5a, 0x51, 0x3d, 0x3d, 0x0d, 0x0a, 0x4f, 0x72, 0x69, 0x67, "
- "0x69, 0x6e, 0x3a, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x31, 0x32, 0x37, 0x2e, 0x30, "
- "0x2e, 0x30, 0x2e, 0x31, 0x0d, 0x0a, 0x53, 0x65, 0x63, 0x2d, 0x57, 0x65, 0x62, 0x53, 0x6f, 0x63, "
- "0x6b, 0x65, 0x74, 0x2d, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x31, 0x33, 0x0d, "
- "0x0a, 0x47, 0x45, 0x54, 0x20, 0x2f, 0x65, 0x63, 0x68, 0x6f, 0x20, 0x48, 0x54, 0x54, 0x50, 0x2f, "
- "0x31, 0x2e, 0x31, 0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20, 0x31, 0x32, 0x37, 0x2e, 0x30, "
- "0x2e, 0x30, 0x2e, 0x31, 0x0d, 0x0a, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x3a, 0x20, 0x77, "
- "0x65, 0x62, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, "
- "0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x0d, 0x0a, 0x53, "
- "0x65, 0x63, 0x2d, 0x57, 0x65, 0x62, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x2d, 0x4b, 0x65, 0x79, "
- "0x3a, 0x20, 0x64, 0x47, 0x68, 0x6c, 0x49, 0x48, 0x4e, 0x68, 0x62, 0x58, 0x42, 0x73, 0x5a, 0x53, "
- "0x42, 0x75, 0x62, 0x32, 0x35, 0x6a, 0x5a, 0x51, 0x3d, 0x3d, 0x0d, 0x0a, 0x4f, 0x72, 0x69, 0x67, "
- "0x69, 0x6e, 0x3a, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x31, 0x32, 0x37, 0x2e, 0x30, "
- "0x2e, 0x30, 0x2e, 0x31, 0x0d, 0x0a, 0x53, 0x65, 0x63, 0x2d, 0x57, 0x65, 0x62, 0x53, 0x6f, 0x63, "
- "0x6b, 0x65, 0x74, 0x2d, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x31, 0x33, 0x0d, "
- "0x0a, 0xc0, 0x80, 0xef, 0xb7, 0x90, 0x47, 0x45, 0x54, 0x20, 0x2f, 0x65, 0x63, 0x68, 0x6f, 0x20, "
- "0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31, 0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20, "
- "0x31, 0x32, 0x37, 0x2e, 0x30, 0x2e, 0x30, 0x2e, 0x31, 0x0d, 0x0a, 0x55, 0x70, 0x67, 0x72, 0x61, "
- "0x64, 0x65, 0x3a, 0x20, 0x77, 0x65, 0x62, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x0d, 0x0a, 0x43, "
- "0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x55, 0x70, 0x67, 0x72, 0x61, "
- "0x64, 0x65, 0x0d, 0x0a, 0x53, 0x65, 0x63, 0x2d, 0x57, 0x65, 0x62, 0x53, 0x6f, 0x63, 0x6b, 0x65, "
- "0x74, 0x2d, 0x4b, 0x65, 0x79, 0x3a, 0x20, 0x64, 0x47, 0x68, 0x6c, 0x49, 0x48, 0x4e, 0x68, 0x62, "
- "0x58, 0x42, 0x73, 0x5a, 0x53, 0x42, 0x75, 0x62, 0x32, 0x35, 0x6a, 0x5a, 0x51, 0x3d, 0x3d, 0x0d, "
- "0x0a, 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x3a, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, "
- "0x31, 0x32, 0x37, 0x2e, 0x30, 0x2e, 0x30, 0x2e, 0x31, 0x0d, 0x0a, 0x53, 0x65, 0x63, 0x2d, 0x57, "
- "0x65, 0x62, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x2d, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, "
- "0x3a, 0x20, 0x31, 0x33, 0x0d, 0x0a, 0x47, 0x45, 0x54, 0x20, 0x2f, 0x65, 0x63, 0x68, 0x6f, 0x20, "
- "0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31, 0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20, "
- "0x31, 0x32, 0x37, 0x2e, 0x30, 0x2e, 0x30, 0x2e, 0x31, 0x0d, 0x0a, 0x55, 0x70, 0x67, 0x72, 0x61, "
- "0x64, 0x65, 0x3a, 0x20, 0x77, 0x65, 0x62, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x0d, 0x0a, 0x43, "
- "0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x55, 0x70, 0x67, 0x72, 0x61, "
- "0x64, 0x65, 0x0d, 0x0a, 0x53, 0x65, 0x63, 0x2d, 0x57, 0x65, 0x62, 0x53, 0x6f, 0x63, 0x6b, 0x65, "
- "0x74, 0x2d, 0x4b, 0x65, 0x79, 0x3a, 0x20, 0x64, 0x47, 0x68, 0x6c, 0x49, 0x48, 0x4e, 0x68, 0x62, "
- "0x58, 0x42, 0x73, 0x5a, 0x53, 0x42, 0x75, 0x62, 0x32, 0x35, 0x6a, 0x5a, 0x51, 0x3d, 0x3d, 0x0d, "
- "0x0a, 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x3a, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, "
- "0x31, 0x32, 0x37, 0x2e, 0x30, 0x2e, 0x30, 0x2e, 0x31, 0x0d, 0x0a, 0x53, 0x65, 0x63, 0x2d, 0x57, "
- "0x65, 0x62, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x2d, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, "
- "0x3a, 0x20, 0x31, 0x33, 0x0d, 0x0a, 0xc2, 0x47, 0x45, 0x54, 0x20, 0x2f, 0x65, 0x63, 0x68, 0x6f, "
- "0x20, 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31, 0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, "
- "0x20, 0x31, 0x32, 0x37, 0x2e, 0x30, 0x2e, 0x30, 0x2e, 0x31, 0x0d, 0x0a, 0x55, 0x70, 0x67, 0x72, "
- "0x61, 0x64, 0x0d, 0x0a, }"
- }, { 0, 4 }, 1 },
- { { NULL, "\x0d\x0a\x0d\x0a",
- "0x47, 0x45, 0x54, 0x20, 0x2f, 0x65, 0x63, 0x68, 0x6f, 0x20, 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, "
- "0x2e, 0x31, 0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20, 0x31, 0x32, 0x37, 0x2e, 0x30, 0x2e, "
- "0x30, 0x2e, 0x31, 0x0d, 0x0a, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x3a, 0x20, 0x77, 0x65, "
- "0x62, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, "
- "0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x0d, 0x0a, 0x53, 0x65, "
- "0x63, 0x2d, 0x57, 0x65, 0x62, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x2d, 0x4b, 0x65, 0x79, 0x3a, "
- "0x20, 0x64, 0x47, 0x68, 0x6c, 0x49, 0x48, 0x4e, 0x68, 0x62, 0x58, 0x42, 0x73, 0x5a, 0x53, 0x42, "
- "0x75, 0x62, 0x32, 0x35, 0x6a, 0x5a, 0x51, 0x3d, 0x3d, 0x0d, 0x0a, 0x4f, 0x72, 0x69, 0x67, 0x69, "
- "0x6e, 0x3a, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x31, 0x32, 0x37, 0x2e, 0x30, 0x2e, "
- "0x30, 0x2e, 0x31, 0x0d, 0x0a, 0x53, 0x65, 0x63, 0x2d, 0x57, 0x65, 0x62, 0x53, 0x6f, 0x63, 0x6b, "
- "0x65, 0x74, 0x2d, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x31, 0x33, 0x0d, 0x0a, "
- "0xef, 0xbb, 0xbf, 0xc2, 0x47, 0x45, 0x54, 0x20, 0x2f, 0x65, 0x63, 0x68, 0x6f, 0x20, 0x48, 0x54, "
- "0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31, 0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20, 0x31, 0x32, "
- "0x37, 0x2e, 0x30, 0x2e, 0x30, 0x2e, 0x31, 0x0d, 0x0a, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, "
- "0x3a, 0x20, 0x77, 0x65, 0x62, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, "
- "0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x0d, 0x0a, (2048){ 0x0d, 0x0a}"
- }, { 0, 4 }, 1 },
- };
- static const int ring_size(struct ring *r)
- {
- return sizeof(r->buf);
- }
- static const int ring_used(struct ring *r)
- {
- return (r->head - r->tail) & (ring_size(r) - 1);
- }
- static const int ring_free(struct ring *r)
- {
- return (ring_size(r) - 1) - ring_used(r);
- }
- static const int ring_get_one(struct ring *r)
- {
- int n = r->buf[r->tail] & 255;
- if (r->tail == r->head)
- return -1;
- r->tail++;
- if (r->tail == ring_size(r))
- r->tail = 0;
- return n;
- }
- static int hex(char c)
- {
- if (c >= '0' && c <= '9')
- return c -'0';
- if (c >= 'a' && c <= 'f')
- return c - 'a' + 10;
- if (c >='A' && c <= 'F')
- return c - 'A' + 10;
- return -1;
- }
- static int
- fuzxy_tok(const char **src, unsigned char **buf, int *len)
- {
- unsigned char *start;
- unsigned int count, rlen;
- while (**src) {
- if (**src == ' ' || **src == ',' || **src == '\n') {
- (*src)++;
- continue;
- }
- if ((*src)[0] == '}') {
- (*src)++;
- return 0;
- }
- if ((*src)[0] == '0' && (*src)[1] == 'x') {
- if (!len) {
- lwsl_err("out of space\n");
- return -1;
- }
- ((*buf)++)[0] = (hex((*src)[2]) << 4) | hex((*src)[3]);
- *src += 4;
- (*len)--;
- }
- if (*src[0] == '(') {
- start = *buf;
- (*src)++;
- count = atoi(*src) - 1;
- lwsl_err("count %d\n", count);
- while (**src && **src != ')')
- (*src)++;
- if (!(*src)[0]) {
- lwsl_err("unexpected end in (\n");
- return -1;
- }
- (*src)++;
- while (**src == ' ')
- (*src)++;
- if (**src != '{') {
- lwsl_err("missing {\n");
- return -1;
- }
- (*src)++;
- if (fuzxy_tok(src, buf, len))
- return -1;
- rlen = *buf - start;
- while (count--) {
- if (*len < rlen) {
- lwsl_err("out of space\n");
- return -1;
- }
- memcpy(*buf, start, rlen);
- *buf += rlen;
- *len -= rlen;
- }
- }
- }
- return 0;
- }
- static int
- fuzxy_create_pattern(const char *src, unsigned char *buf, int len)
- {
- unsigned char *old = buf;
- int n;
- while (*src && (*src == '{' || *src == ' '))
- src++;
- if (!*src)
- return -1;
- n = fuzxy_tok(&src, &buf, &len);
- if (n)
- return -1;
- return buf - old;
- }
- void sighandler(int sig)
- {
- force_exit = 1;
- }
- static struct option options[] = {
- { "help", no_argument, NULL, 'h' },
- { "debug", required_argument, NULL, 'd' },
- { "port", required_argument, NULL, 'p' },
- { "ssl", no_argument, NULL, 's' },
- { "allow-non-ssl", no_argument, NULL, 'a' },
- { "interface", required_argument, NULL, 'i' },
- { "closetest", no_argument, NULL, 'c' },
- { "libev", no_argument, NULL, 'e' },
- #ifndef LWS_NO_DAEMONIZE
- { "daemonize", no_argument, NULL, 'D' },
- #endif
- { "resource_path", required_argument, NULL, 'r' },
- { NULL, 0, 0, 0 }
- };
- static struct pollfd pfd[128];
- static struct state state[128];
- static int pfds = 0;
- static void close_and_remove_fd(int index)
- {
- int n;
- lwsl_notice("%s: closing index %d\n", __func__, index);
- close(pfd[index].fd);
- pfd[index].fd = -1;
- n = state[index].twin;
- if (n) {
- assert(state[n].twin == index);
- }
- state[index].type = FZY_S_DEAD;
- if (index == pfds - 1) {
- if (state[index].twin)
- state[state[index].twin].twin = 0;
- state[index].twin = 0;
- goto bail;
- }
- /* swap the end guy into the deleted guy and trim back one */
- if (state[pfds - 1].twin) {
- state[state[pfds - 1].twin].twin = index;
- if (n && n == pfds - 1)
- n = index;
- }
- /* swap the last guy into dead guy's place and trim by one */
- pfd[index] = pfd[pfds - 1];
- state[index] = state[pfds - 1];
- if (n) {
- pfds--;
- state[n].twin = 0;
- close_and_remove_fd(n);
- return;
- }
- bail:
- pfds--;
- }
- static void construct_state(int n, enum types s, int flags)
- {
- memset(&state[n], 0, sizeof state[n]);
- state[n].type = s;
- pfd[n].events = flags | POLLHUP;
- }
- static int
- fuzxy_listen(const char *interface_name, int port, int *sockfd)
- {
- struct sockaddr_in serv_addr4;
- socklen_t len = sizeof(struct sockaddr);
- struct sockaddr_in sin;
- int n, opt = 1;
- *sockfd = socket(AF_INET, SOCK_STREAM, 0);
- if (*sockfd == -1) {
- lwsl_err("ERROR opening socket\n");
- goto bail1;
- }
- if (setsockopt(*sockfd, SOL_SOCKET, SO_REUSEADDR,
- (const void *)&opt, sizeof(opt)) < 0) {
- lwsl_err("unable to set listen socket options\n");
- goto bail2;
- }
- bzero((char *) &serv_addr4, sizeof(serv_addr4));
- serv_addr4.sin_addr.s_addr = INADDR_ANY;
- serv_addr4.sin_family = AF_INET;
- if (interface_name[0] &&
- lws_interface_to_sa(0, interface_name, (struct sockaddr_in *)
- (struct sockaddr *)&serv_addr4,
- sizeof(serv_addr4)) < 0) {
- lwsl_err("Unable to find interface %s\n", interface_name);
- goto bail2;
- }
- serv_addr4.sin_port = htons(port);
- n = bind(*sockfd, (struct sockaddr *)&serv_addr4,
- sizeof(serv_addr4));
- if (n < 0) {
- lwsl_err("ERROR on binding to port %d (%d %d)\n",
- port, n, errno);
- goto bail2;
- }
- if (getsockname(*sockfd, (struct sockaddr *)&sin, &len) == -1)
- lwsl_warn("getsockname: %s\n", strerror(errno));
- else
- port = ntohs(sin.sin_port);
- listen(*sockfd, SOMAXCONN);
- return 0;
- bail2:
- close(*sockfd);
- bail1:
- return -1;
- }
- static int fuzz(int n, char *out, int len)
- {
- struct state *s = &state[n];
- const struct test *t = &tests[which];
- int m = 0;
- int c;
- while (m < len) {
- switch (s->fp) {
- case FZY_FP_SEARCH:
- if (t->s[0] == NULL) {
- s->fuzc = 0;
- s->is_pending = 0;
- s->fp = FZY_FP_SEARCH2;
- goto search2;
- }
- c = ring_get_one(&state[s->twin].in);
- if (c < 0)
- return m;
- if (c == tests[which].s[0][s->fuzc++]) {
- if (s->fuzc == t->len[0]) {
- s->fuzc = 0;
- s->fp = FZY_FP_SEARCH2;
- }
- } else
- s->fuzc = 0;
- out[m++] = c;
- break;
- case FZY_FP_SEARCH2:
- search2:
- if (tests[which].s[1] == NULL) {
- s->fuzc = 0;
- s->is_pending = 0;
- s->fp = FZY_FP_INJECT_PREPARE;
- goto inject;
- }
- c = ring_get_one(&state[s->twin].in);
- if (c < 0)
- return m;
- if (c == tests[which].s[1][s->fuzc++]) {
- if (s->fuzc == tests[which].len[1]) {
- lwsl_notice("+++++++fuzzer hit...\n");
- s->fuzc = 0;
- s->fp = FZY_FP_INJECT_PREPARE;
- s->is_pending = !t->swallow;
- s->pending = c;
- goto inject;
- }
- } else
- s->fuzc = 0;
- if (!t->swallow)
- out[m++] = c;
- break;
- case FZY_FP_INJECT_PREPARE:
- inject:
- s->inject_len = fuzxy_create_pattern(t->s[2],
- s->buf, sizeof(s->buf));
- if (s->inject_len == (unsigned int) -1)
- return -1;
- s->fp = FZY_FP_INJECT;
- /* fallthru */
- case FZY_FP_INJECT:
- out[m++] = s->buf[s->fuzc++];
- if (s->fuzc == s->inject_len)
- s->fp = FZY_FP_PENDING;
- break;
- case FZY_FP_PENDING:
- if (s->is_pending)
- out[m++] = s->pending;
- s->fp = FZY_FP_SEARCH;
- s->fuzc = 0;
- break;
- }
- }
- return m;
- }
- static int
- handle_accept(int n)
- {
- struct addrinfo ai, *res, *result;
- struct sockaddr_in serv_addr4;
- struct state *s = &state[n];
- void *p = NULL;
- int m, sockfd;
- while (1) {
- m = ring_get_one(&s->in);
- if (m < 0)
- return 0;
- switch (s->pp) {
- case FZY_PP_CONNECT:
- if (m != "CONNECT "[s->ppc++]) {
- lwsl_notice("failed CONNECT match\n");
- return 1;
- }
- if (s->ppc == 8) {
- s->pp = FZY_PP_ADDRESS;
- s->ppc = 0;
- }
- break;
- case FZY_PP_ADDRESS:
- if (m == ':') {
- s->address[s->ppc++] = '\0';
- s->pp = FZY_PP_PORT;
- s->ppc = 0;
- break;
- }
- if (m == ' ') {
- s->address[s->ppc++] = '\0';
- s->pp = FZY_PP_CRLFS;
- s->ppc = 0;
- break;
- }
- s->address[s->ppc++] = m;
- if (s->ppc == sizeof(s->address)) {
- lwsl_notice("Failed on address length\n");
- return 1;
- }
- break;
- case FZY_PP_PORT:
- if (m == ' ') {
- s->pp = FZY_PP_CRLFS;
- s->ppc = 0;
- break;
- }
- if (m >= '0' && m <= '9') {
- s->port *= 10;
- s->port += m - '0';
- break;
- }
- return 1;
- case FZY_PP_CRLFS:
- if (m != "\x0d\x0a\x0d\x0a"[s->ppc++])
- s->ppc = 0;
- if (s->ppc != 4)
- break;
- s->type = FZY_S_PROXIED;
- memset (&ai, 0, sizeof ai);
- ai.ai_family = PF_UNSPEC;
- ai.ai_socktype = SOCK_STREAM;
- ai.ai_flags = AI_CANONNAME;
- if (getaddrinfo(s->address, NULL, &ai, &result)) {
- lwsl_notice("failed to lookup %s\n",
- s->address);
- return 1;
- }
- res = result;
- while (!p && res) {
- switch (res->ai_family) {
- case AF_INET:
- p = &((struct sockaddr_in *)res->
- ai_addr)->sin_addr;
- break;
- }
- res = res->ai_next;
- }
- if (!p) {
- lwsl_notice("Failed to get address result %s\n",
- s->address);
- freeaddrinfo(result);
- return 1;
- }
- serv_addr4.sin_family = AF_INET;
- serv_addr4.sin_addr = *((struct in_addr *)p);
- serv_addr4.sin_port = htons(s->port);
- bzero(&serv_addr4.sin_zero, 8);
- freeaddrinfo(result);
- lwsl_err("Conn %d req '%s' port %d\n", n,
- s->address, s->port);
- /* we need to open the associated onward connection */
- sockfd = socket(AF_INET, SOCK_STREAM, 0);
- if (sockfd < 0) {
- lwsl_err("Could not get socket\n");
- return -1;
- }
- if (connect(sockfd, (struct sockaddr *)&serv_addr4,
- sizeof(struct sockaddr)) == -1 ||
- errno == EISCONN) {
- close(sockfd);
- lwsl_err("proxied onward connection failed\n");
- return 1;
- }
- s->twin = pfds;
- construct_state(pfds, FZY_S_ONWARD,
- POLLOUT | POLLIN | POLLERR);
- state[pfds].twin = n;
- lwsl_notice("binding conns %d and %d\n", n, pfds);
- state[pfds].outbound = s->outbound;
- state[pfds].ppc = 0;
- pfd[pfds++].fd = sockfd;
- lwsl_notice("onward connection in progress\n");
- if (ring_used(&s->in))
- pfd[s->twin].events |= POLLOUT;
- if (write(pfd[n].fd,
- "HTTP/1.0 200 \x0d\x0a\x0d\x0a", 17) < 17)
- return 1;
- }
- }
- return 0;
- }
- static void sigpipe_handler(int x)
- {
- }
- int
- main(int argc, char **argv)
- {
- char interface_name[128] = "", interface_name_local[128] = "lo";
- int port_local = 8880, accept_fd;
- struct sockaddr_in cli_addr;
- int debug_level = 7;
- socklen_t clilen;
- struct state *s;
- char out[4096];
- int opts = 0;
- int n = 0, m;
- #ifndef _WIN32
- /* LOG_PERROR is not POSIX standard, and may not be portable */
- #ifdef __sun
- int syslog_options = LOG_PID;
- #else
- int syslog_options = LOG_PID | LOG_PERROR;
- #endif
- #endif
- #ifndef LWS_NO_DAEMONIZE
- int daemonize = 0;
- #endif
- signal(SIGPIPE, sigpipe_handler);
- while (n >= 0) {
- n = getopt_long(argc, argv, "eci:hsap:d:Dr:", options, NULL);
- if (n < 0)
- continue;
- switch (n) {
- case 'e':
- opts |= LWS_SERVER_OPTION_LIBEV;
- break;
- #ifndef LWS_NO_DAEMONIZE
- case 'D':
- daemonize = 1;
- #if !defined(_WIN32) && !defined(__sun)
- syslog_options &= ~LOG_PERROR;
- #endif
- break;
- #endif
- case 'd':
- debug_level = atoi(optarg);
- break;
- case 'p':
- port_local = atoi(optarg);
- break;
- case 'i':
- strncpy(interface_name, optarg, sizeof interface_name);
- interface_name[(sizeof interface_name) - 1] = '\0';
- break;
- case 'h':
- fprintf(stderr, "Usage: libwebsockets-test-fuzxy "
- "[--port=<p>] [--ssl] "
- "[-d <log bitfield>] "
- "[--resource_path <path>]\n");
- exit(1);
- }
- }
- #if !defined(LWS_NO_DAEMONIZE) && !defined(WIN32)
- /*
- * normally lock path would be /var/lock/lwsts or similar, to
- * simplify getting started without having to take care about
- * permissions or running as root, set to /tmp/.lwsts-lock
- */
- if (daemonize && lws_daemonize("/tmp/.lwsts-lock")) {
- fprintf(stderr, "Failed to daemonize\n");
- return 1;
- }
- #endif
- signal(SIGINT, sighandler);
- #ifndef _WIN32
- /* we will only try to log things according to our debug_level */
- setlogmask(LOG_UPTO (LOG_DEBUG));
- openlog("fuzxy", syslog_options, LOG_DAEMON);
- #endif
- /* tell the library what debug level to emit and to send it to syslog */
- lws_set_log_level(debug_level, lwsl_emit_syslog);
- lwsl_notice("libwebsockets fuzzing proxy - license LGPL2.1+SLE\n");
- lwsl_notice("(C) Copyright 2016 Andy Green <andy@warmcat.com>\n");
- /* listen on local side */
- if (fuzxy_listen(interface_name, port_local, &pfd[pfds].fd)) {
- lwsl_err("Failed to listen on local side\n");
- goto bail1;
- }
- construct_state(pfds, FZY_S_LISTENING, POLLIN | POLLERR);
- pfds++;
- lwsl_notice("Local side listening on %s:%u\n",
- interface_name_local, port_local);
- while (!force_exit) {
- m = poll(pfd, pfds, 50);
- if (m < 0)
- continue;
- for (n = 0; n < pfds; n++) {
- s = &state[n];
- if (s->type == FZY_S_LISTENING &&
- (pfd[n].revents & POLLIN)) {
- /* first do the accept entry */
- clilen = sizeof(cli_addr);
- accept_fd = accept(pfd[0].fd,
- (struct sockaddr *)&cli_addr, &clilen);
- if (accept_fd < 0) {
- if (errno == EAGAIN ||
- errno == EWOULDBLOCK)
- continue;
- lwsl_warn("ERROR on accept: %s\n",
- strerror(errno));
- continue;
- }
- construct_state(pfds, FZY_S_ACCEPTED,
- POLLIN | POLLERR);
- state[pfds].outbound = n == 0;
- state[pfds].pp = FZY_PP_CONNECT;
- state[pfds].ppc = 0;
- pfd[pfds++].fd = accept_fd;
- lwsl_notice("new connect accepted\n");
- continue;
- }
- if (pfd[n].revents & POLLIN) {
- assert(ring_free(&s->in));
- m = (ring_size(&s->in) - 1) -
- s->in.head;
- if (s->in.head == ring_size(&s->in) - 1 &&
- s->in.tail)
- m = 1;
- m = read(pfd[n].fd, s->in.buf + s->in.head, m);
- // lwsl_notice("read %d\n", m);
- if (m <= 0) {
- lwsl_err("Error on read\n");
- goto drop;
- }
- s->in.head += m;
- if (s->in.head == ring_size(&s->in))
- s->in.head = 0;
- switch (s->type) {
- case FZY_S_ACCEPTED: /* parse proxy CONNECT */
- if (handle_accept(n))
- goto drop;
- break;
- case FZY_S_PROXIED:
- case FZY_S_ONWARD:
- if (ring_used(&s->in))
- pfd[s->twin].events |= POLLOUT;
- break;
- default:
- assert(0);
- break;
- }
- if (s->in.head == s->in.tail) {
- s->in.head = s->in.tail = 0;
- pfd[n].events |= POLLIN;
- }
- if (!ring_free(&s->in))
- pfd[n].events &= ~POLLIN;
- }
- if (pfd[n].revents & POLLOUT) {
- switch (s->type) {
- case FZY_S_PROXIED:
- case FZY_S_ONWARD:
- /*
- * draw down enough of the partner's
- * in ring to either exhaust it
- * or fill an output buffer
- */
- m = fuzz(n, out, sizeof(out));
- if (m < 0) {
- lwsl_err("Error on fuzz\n");
- goto drop;
- }
- lwsl_notice("got block %d\n", m);
- if (m) {
- m = write(pfd[n].fd, out, m);
- if (m <= 0) {
- lwsl_err("Error on write\n");
- goto drop;
- } else
- pfd[s->twin].events &= ~POLLIN;
- } else {
- pfd[n].events &= ~POLLOUT;
- if (ring_free(&state[s->twin].in))
- pfd[s->twin].events |= POLLIN;
- }
- break;
- default:
- break;
- }
- }
- continue;
- drop:
- close_and_remove_fd(n);
- n--; /* redo this slot */
- }
- }
- bail1:
- lwsl_notice("%s exited cleanly\n", argv[0]);
- #ifndef _WIN32
- closelog();
- #endif
- return 0;
- }
|