summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/libuv/samples/socks5-proxy
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/libuv/samples/socks5-proxy')
-rw-r--r--3rdparty/libuv/samples/socks5-proxy/.gitignore21
-rw-r--r--3rdparty/libuv/samples/socks5-proxy/LICENSE53
-rw-r--r--3rdparty/libuv/samples/socks5-proxy/Makefile46
-rw-r--r--3rdparty/libuv/samples/socks5-proxy/build.gyp46
-rw-r--r--3rdparty/libuv/samples/socks5-proxy/client.c737
-rw-r--r--3rdparty/libuv/samples/socks5-proxy/defs.h139
-rw-r--r--3rdparty/libuv/samples/socks5-proxy/getopt.c131
-rw-r--r--3rdparty/libuv/samples/socks5-proxy/main.c99
-rw-r--r--3rdparty/libuv/samples/socks5-proxy/s5.c271
-rw-r--r--3rdparty/libuv/samples/socks5-proxy/s5.h94
-rw-r--r--3rdparty/libuv/samples/socks5-proxy/server.c241
-rw-r--r--3rdparty/libuv/samples/socks5-proxy/util.c72
12 files changed, 0 insertions, 1950 deletions
diff --git a/3rdparty/libuv/samples/socks5-proxy/.gitignore b/3rdparty/libuv/samples/socks5-proxy/.gitignore
deleted file mode 100644
index c177f374510..00000000000
--- a/3rdparty/libuv/samples/socks5-proxy/.gitignore
+++ /dev/null
@@ -1,21 +0,0 @@
-# Copyright StrongLoop, Inc. All rights reserved.
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to
-# deal in the Software without restriction, including without limitation the
-# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
-# sell copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-# IN THE SOFTWARE.
-
-/build/
diff --git a/3rdparty/libuv/samples/socks5-proxy/LICENSE b/3rdparty/libuv/samples/socks5-proxy/LICENSE
deleted file mode 100644
index 63c1447fc55..00000000000
--- a/3rdparty/libuv/samples/socks5-proxy/LICENSE
+++ /dev/null
@@ -1,53 +0,0 @@
-Files: *
-========
-
-Copyright StrongLoop, Inc. All rights reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to
-deal in the Software without restriction, including without limitation the
-rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
-sell copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-IN THE SOFTWARE.
-
-
-Files: getopt.c
-===============
-
-Copyright (c) 1987, 1993, 1994
-The Regents of the University of California. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
diff --git a/3rdparty/libuv/samples/socks5-proxy/Makefile b/3rdparty/libuv/samples/socks5-proxy/Makefile
deleted file mode 100644
index ca43985ec80..00000000000
--- a/3rdparty/libuv/samples/socks5-proxy/Makefile
+++ /dev/null
@@ -1,46 +0,0 @@
-# Copyright StrongLoop, Inc. All rights reserved.
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to
-# deal in the Software without restriction, including without limitation the
-# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
-# sell copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-# IN THE SOFTWARE.
-
-BUILDTYPE ?= Debug
-BUILDDIR ?= build
-GYP ?= gyp
-V ?=
-
-SOURCES := client.c defs.h getopt.c main.c s5.c s5.h server.c util.c
-
-.PHONY: all clean
-
-all: $(BUILDDIR)/$(BUILDTYPE)/s5-proxy
-
-clean:
- $(RM) $(BUILDDIR)
-
-$(BUILDDIR)/$(BUILDTYPE)/s5-proxy: $(BUILDDIR)/Makefile $(SOURCES)
- $(MAKE) -C $(BUILDDIR) V=$(V)
-
-$(BUILDDIR)/Makefile: ../../common.gypi build.gyp
- $(GYP) \
- -Duv_library=static_library \
- -Goutput_dir=. \
- -I../../common.gypi \
- -f make \
- --depth=. \
- --generator-output=$(BUILDDIR) \
- build.gyp
diff --git a/3rdparty/libuv/samples/socks5-proxy/build.gyp b/3rdparty/libuv/samples/socks5-proxy/build.gyp
deleted file mode 100644
index 771a1e146db..00000000000
--- a/3rdparty/libuv/samples/socks5-proxy/build.gyp
+++ /dev/null
@@ -1,46 +0,0 @@
-# Copyright StrongLoop, Inc. All rights reserved.
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to
-# deal in the Software without restriction, including without limitation the
-# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
-# sell copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-# IN THE SOFTWARE.
-
-{
- 'targets': [
- {
- 'dependencies': ['../../uv.gyp:libuv'],
- 'target_name': 's5-proxy',
- 'type': 'executable',
- 'sources': [
- 'client.c',
- 'defs.h',
- 'main.c',
- 's5.c',
- 's5.h',
- 'server.c',
- 'util.c',
- ],
- 'conditions': [
- ['OS=="win"', {
- 'defines': ['HAVE_UNISTD_H=0'],
- 'sources': ['getopt.c']
- }, {
- 'defines': ['HAVE_UNISTD_H=1']
- }]
- ]
- }
- ]
-}
diff --git a/3rdparty/libuv/samples/socks5-proxy/client.c b/3rdparty/libuv/samples/socks5-proxy/client.c
deleted file mode 100644
index ae9913a1c6e..00000000000
--- a/3rdparty/libuv/samples/socks5-proxy/client.c
+++ /dev/null
@@ -1,737 +0,0 @@
-/* Copyright StrongLoop, Inc. All rights reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
-#include "defs.h"
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-
-/* A connection is modeled as an abstraction on top of two simple state
- * machines, one for reading and one for writing. Either state machine
- * is, when active, in one of three states: busy, done or stop; the fourth
- * and final state, dead, is an end state and only relevant when shutting
- * down the connection. A short overview:
- *
- * busy done stop
- * ----------|---------------------------|--------------------|------|
- * readable | waiting for incoming data | have incoming data | idle |
- * writable | busy writing out data | completed write | idle |
- *
- * We could remove the done state from the writable state machine. For our
- * purposes, it's functionally equivalent to the stop state.
- *
- * When the connection with upstream has been established, the client_ctx
- * moves into a state where incoming data from the client is sent upstream
- * and vice versa, incoming data from upstream is sent to the client. In
- * other words, we're just piping data back and forth. See conn_cycle()
- * for details.
- *
- * An interesting deviation from libuv's I/O model is that reads are discrete
- * rather than continuous events. In layman's terms, when a read operation
- * completes, the connection stops reading until further notice.
- *
- * The rationale for this approach is that we have to wait until the data
- * has been sent out again before we can reuse the read buffer.
- *
- * It also pleasingly unifies with the request model that libuv uses for
- * writes and everything else; libuv may switch to a request model for
- * reads in the future.
- */
-enum conn_state {
- c_busy, /* Busy; waiting for incoming data or for a write to complete. */
- c_done, /* Done; read incoming data or write finished. */
- c_stop, /* Stopped. */
- c_dead
-};
-
-/* Session states. */
-enum sess_state {
- s_handshake, /* Wait for client handshake. */
- s_handshake_auth, /* Wait for client authentication data. */
- s_req_start, /* Start waiting for request data. */
- s_req_parse, /* Wait for request data. */
- s_req_lookup, /* Wait for upstream hostname DNS lookup to complete. */
- s_req_connect, /* Wait for uv_tcp_connect() to complete. */
- s_proxy_start, /* Connected. Start piping data. */
- s_proxy, /* Connected. Pipe data back and forth. */
- s_kill, /* Tear down session. */
- s_almost_dead_0, /* Waiting for finalizers to complete. */
- s_almost_dead_1, /* Waiting for finalizers to complete. */
- s_almost_dead_2, /* Waiting for finalizers to complete. */
- s_almost_dead_3, /* Waiting for finalizers to complete. */
- s_almost_dead_4, /* Waiting for finalizers to complete. */
- s_dead /* Dead. Safe to free now. */
-};
-
-static void do_next(client_ctx *cx);
-static int do_handshake(client_ctx *cx);
-static int do_handshake_auth(client_ctx *cx);
-static int do_req_start(client_ctx *cx);
-static int do_req_parse(client_ctx *cx);
-static int do_req_lookup(client_ctx *cx);
-static int do_req_connect_start(client_ctx *cx);
-static int do_req_connect(client_ctx *cx);
-static int do_proxy_start(client_ctx *cx);
-static int do_proxy(client_ctx *cx);
-static int do_kill(client_ctx *cx);
-static int do_almost_dead(client_ctx *cx);
-static int conn_cycle(const char *who, conn *a, conn *b);
-static void conn_timer_reset(conn *c);
-static void conn_timer_expire(uv_timer_t *handle, int status);
-static void conn_getaddrinfo(conn *c, const char *hostname);
-static void conn_getaddrinfo_done(uv_getaddrinfo_t *req,
- int status,
- struct addrinfo *ai);
-static int conn_connect(conn *c);
-static void conn_connect_done(uv_connect_t *req, int status);
-static void conn_read(conn *c);
-static void conn_read_done(uv_stream_t *handle,
- ssize_t nread,
- const uv_buf_t *buf);
-static void conn_alloc(uv_handle_t *handle, size_t size, uv_buf_t *buf);
-static void conn_write(conn *c, const void *data, unsigned int len);
-static void conn_write_done(uv_write_t *req, int status);
-static void conn_close(conn *c);
-static void conn_close_done(uv_handle_t *handle);
-
-/* |incoming| has been initialized by server.c when this is called. */
-void client_finish_init(server_ctx *sx, client_ctx *cx) {
- conn *incoming;
- conn *outgoing;
-
- cx->sx = sx;
- cx->state = s_handshake;
- s5_init(&cx->parser);
-
- incoming = &cx->incoming;
- incoming->client = cx;
- incoming->result = 0;
- incoming->rdstate = c_stop;
- incoming->wrstate = c_stop;
- incoming->idle_timeout = sx->idle_timeout;
- CHECK(0 == uv_timer_init(sx->loop, &incoming->timer_handle));
-
- outgoing = &cx->outgoing;
- outgoing->client = cx;
- outgoing->result = 0;
- outgoing->rdstate = c_stop;
- outgoing->wrstate = c_stop;
- outgoing->idle_timeout = sx->idle_timeout;
- CHECK(0 == uv_tcp_init(cx->sx->loop, &outgoing->handle.tcp));
- CHECK(0 == uv_timer_init(cx->sx->loop, &outgoing->timer_handle));
-
- /* Wait for the initial packet. */
- conn_read(incoming);
-}
-
-/* This is the core state machine that drives the client <-> upstream proxy.
- * We move through the initial handshake and authentication steps first and
- * end up (if all goes well) in the proxy state where we're just proxying
- * data between the client and upstream.
- */
-static void do_next(client_ctx *cx) {
- int new_state;
-
- ASSERT(cx->state != s_dead);
- switch (cx->state) {
- case s_handshake:
- new_state = do_handshake(cx);
- break;
- case s_handshake_auth:
- new_state = do_handshake_auth(cx);
- break;
- case s_req_start:
- new_state = do_req_start(cx);
- break;
- case s_req_parse:
- new_state = do_req_parse(cx);
- break;
- case s_req_lookup:
- new_state = do_req_lookup(cx);
- break;
- case s_req_connect:
- new_state = do_req_connect(cx);
- break;
- case s_proxy_start:
- new_state = do_proxy_start(cx);
- break;
- case s_proxy:
- new_state = do_proxy(cx);
- break;
- case s_kill:
- new_state = do_kill(cx);
- break;
- case s_almost_dead_0:
- case s_almost_dead_1:
- case s_almost_dead_2:
- case s_almost_dead_3:
- case s_almost_dead_4:
- new_state = do_almost_dead(cx);
- break;
- default:
- UNREACHABLE();
- }
- cx->state = new_state;
-
- if (cx->state == s_dead) {
- if (DEBUG_CHECKS) {
- memset(cx, -1, sizeof(*cx));
- }
- free(cx);
- }
-}
-
-static int do_handshake(client_ctx *cx) {
- unsigned int methods;
- conn *incoming;
- s5_ctx *parser;
- uint8_t *data;
- size_t size;
- int err;
-
- parser = &cx->parser;
- incoming = &cx->incoming;
- ASSERT(incoming->rdstate == c_done);
- ASSERT(incoming->wrstate == c_stop);
- incoming->rdstate = c_stop;
-
- if (incoming->result < 0) {
- pr_err("read error: %s", uv_strerror(incoming->result));
- return do_kill(cx);
- }
-
- data = (uint8_t *) incoming->t.buf;
- size = (size_t) incoming->result;
- err = s5_parse(parser, &data, &size);
- if (err == s5_ok) {
- conn_read(incoming);
- return s_handshake; /* Need more data. */
- }
-
- if (size != 0) {
- /* Could allow a round-trip saving shortcut here if the requested auth
- * method is S5_AUTH_NONE (provided unauthenticated traffic is allowed.)
- * Requires client support however.
- */
- pr_err("junk in handshake");
- return do_kill(cx);
- }
-
- if (err != s5_auth_select) {
- pr_err("handshake error: %s", s5_strerror(err));
- return do_kill(cx);
- }
-
- methods = s5_auth_methods(parser);
- if ((methods & S5_AUTH_NONE) && can_auth_none(cx->sx, cx)) {
- s5_select_auth(parser, S5_AUTH_NONE);
- conn_write(incoming, "\5\0", 2); /* No auth required. */
- return s_req_start;
- }
-
- if ((methods & S5_AUTH_PASSWD) && can_auth_passwd(cx->sx, cx)) {
- /* TODO(bnoordhuis) Implement username/password auth. */
- }
-
- conn_write(incoming, "\5\377", 2); /* No acceptable auth. */
- return s_kill;
-}
-
-/* TODO(bnoordhuis) Implement username/password auth. */
-static int do_handshake_auth(client_ctx *cx) {
- UNREACHABLE();
- return do_kill(cx);
-}
-
-static int do_req_start(client_ctx *cx) {
- conn *incoming;
-
- incoming = &cx->incoming;
- ASSERT(incoming->rdstate == c_stop);
- ASSERT(incoming->wrstate == c_done);
- incoming->wrstate = c_stop;
-
- if (incoming->result < 0) {
- pr_err("write error: %s", uv_strerror(incoming->result));
- return do_kill(cx);
- }
-
- conn_read(incoming);
- return s_req_parse;
-}
-
-static int do_req_parse(client_ctx *cx) {
- conn *incoming;
- conn *outgoing;
- s5_ctx *parser;
- uint8_t *data;
- size_t size;
- int err;
-
- parser = &cx->parser;
- incoming = &cx->incoming;
- outgoing = &cx->outgoing;
- ASSERT(incoming->rdstate == c_done);
- ASSERT(incoming->wrstate == c_stop);
- ASSERT(outgoing->rdstate == c_stop);
- ASSERT(outgoing->wrstate == c_stop);
- incoming->rdstate = c_stop;
-
- if (incoming->result < 0) {
- pr_err("read error: %s", uv_strerror(incoming->result));
- return do_kill(cx);
- }
-
- data = (uint8_t *) incoming->t.buf;
- size = (size_t) incoming->result;
- err = s5_parse(parser, &data, &size);
- if (err == s5_ok) {
- conn_read(incoming);
- return s_req_parse; /* Need more data. */
- }
-
- if (size != 0) {
- pr_err("junk in request %u", (unsigned) size);
- return do_kill(cx);
- }
-
- if (err != s5_exec_cmd) {
- pr_err("request error: %s", s5_strerror(err));
- return do_kill(cx);
- }
-
- if (parser->cmd == s5_cmd_tcp_bind) {
- /* Not supported but relatively straightforward to implement. */
- pr_warn("BIND requests are not supported.");
- return do_kill(cx);
- }
-
- if (parser->cmd == s5_cmd_udp_assoc) {
- /* Not supported. Might be hard to implement because libuv has no
- * functionality for detecting the MTU size which the RFC mandates.
- */
- pr_warn("UDP ASSOC requests are not supported.");
- return do_kill(cx);
- }
- ASSERT(parser->cmd == s5_cmd_tcp_connect);
-
- if (parser->atyp == s5_atyp_host) {
- conn_getaddrinfo(outgoing, (const char *) parser->daddr);
- return s_req_lookup;
- }
-
- if (parser->atyp == s5_atyp_ipv4) {
- memset(&outgoing->t.addr4, 0, sizeof(outgoing->t.addr4));
- outgoing->t.addr4.sin_family = AF_INET;
- outgoing->t.addr4.sin_port = htons(parser->dport);
- memcpy(&outgoing->t.addr4.sin_addr,
- parser->daddr,
- sizeof(outgoing->t.addr4.sin_addr));
- } else if (parser->atyp == s5_atyp_ipv6) {
- memset(&outgoing->t.addr6, 0, sizeof(outgoing->t.addr6));
- outgoing->t.addr6.sin6_family = AF_INET6;
- outgoing->t.addr6.sin6_port = htons(parser->dport);
- memcpy(&outgoing->t.addr6.sin6_addr,
- parser->daddr,
- sizeof(outgoing->t.addr6.sin6_addr));
- } else {
- UNREACHABLE();
- }
-
- return do_req_connect_start(cx);
-}
-
-static int do_req_lookup(client_ctx *cx) {
- s5_ctx *parser;
- conn *incoming;
- conn *outgoing;
-
- parser = &cx->parser;
- incoming = &cx->incoming;
- outgoing = &cx->outgoing;
- ASSERT(incoming->rdstate == c_stop);
- ASSERT(incoming->wrstate == c_stop);
- ASSERT(outgoing->rdstate == c_stop);
- ASSERT(outgoing->wrstate == c_stop);
-
- if (outgoing->result < 0) {
- /* TODO(bnoordhuis) Escape control characters in parser->daddr. */
- pr_err("lookup error for \"%s\": %s",
- parser->daddr,
- uv_strerror(outgoing->result));
- /* Send back a 'Host unreachable' reply. */
- conn_write(incoming, "\5\4\0\1\0\0\0\0\0\0", 10);
- return s_kill;
- }
-
- /* Don't make assumptions about the offset of sin_port/sin6_port. */
- switch (outgoing->t.addr.sa_family) {
- case AF_INET:
- outgoing->t.addr4.sin_port = htons(parser->dport);
- break;
- case AF_INET6:
- outgoing->t.addr6.sin6_port = htons(parser->dport);
- break;
- default:
- UNREACHABLE();
- }
-
- return do_req_connect_start(cx);
-}
-
-/* Assumes that cx->outgoing.t.sa contains a valid AF_INET/AF_INET6 address. */
-static int do_req_connect_start(client_ctx *cx) {
- conn *incoming;
- conn *outgoing;
- int err;
-
- incoming = &cx->incoming;
- outgoing = &cx->outgoing;
- ASSERT(incoming->rdstate == c_stop);
- ASSERT(incoming->wrstate == c_stop);
- ASSERT(outgoing->rdstate == c_stop);
- ASSERT(outgoing->wrstate == c_stop);
-
- if (!can_access(cx->sx, cx, &outgoing->t.addr)) {
- pr_warn("connection not allowed by ruleset");
- /* Send a 'Connection not allowed by ruleset' reply. */
- conn_write(incoming, "\5\2\0\1\0\0\0\0\0\0", 10);
- return s_kill;
- }
-
- err = conn_connect(outgoing);
- if (err != 0) {
- pr_err("connect error: %s\n", uv_strerror(err));
- return do_kill(cx);
- }
-
- return s_req_connect;
-}
-
-static int do_req_connect(client_ctx *cx) {
- const struct sockaddr_in6 *in6;
- const struct sockaddr_in *in;
- char addr_storage[sizeof(*in6)];
- conn *incoming;
- conn *outgoing;
- uint8_t *buf;
- int addrlen;
-
- incoming = &cx->incoming;
- outgoing = &cx->outgoing;
- ASSERT(incoming->rdstate == c_stop);
- ASSERT(incoming->wrstate == c_stop);
- ASSERT(outgoing->rdstate == c_stop);
- ASSERT(outgoing->wrstate == c_stop);
-
- /* Build and send the reply. Not very pretty but gets the job done. */
- buf = (uint8_t *) incoming->t.buf;
- if (outgoing->result == 0) {
- /* The RFC mandates that the SOCKS server must include the local port
- * and address in the reply. So that's what we do.
- */
- addrlen = sizeof(addr_storage);
- CHECK(0 == uv_tcp_getsockname(&outgoing->handle.tcp,
- (struct sockaddr *) addr_storage,
- &addrlen));
- buf[0] = 5; /* Version. */
- buf[1] = 0; /* Success. */
- buf[2] = 0; /* Reserved. */
- if (addrlen == sizeof(*in)) {
- buf[3] = 1; /* IPv4. */
- in = (const struct sockaddr_in *) &addr_storage;
- memcpy(buf + 4, &in->sin_addr, 4);
- memcpy(buf + 8, &in->sin_port, 2);
- conn_write(incoming, buf, 10);
- } else if (addrlen == sizeof(*in6)) {
- buf[3] = 4; /* IPv6. */
- in6 = (const struct sockaddr_in6 *) &addr_storage;
- memcpy(buf + 4, &in6->sin6_addr, 16);
- memcpy(buf + 20, &in6->sin6_port, 2);
- conn_write(incoming, buf, 22);
- } else {
- UNREACHABLE();
- }
- return s_proxy_start;
- } else {
- pr_err("upstream connection error: %s\n", uv_strerror(outgoing->result));
- /* Send a 'Connection refused' reply. */
- conn_write(incoming, "\5\5\0\1\0\0\0\0\0\0", 10);
- return s_kill;
- }
-
- UNREACHABLE();
- return s_kill;
-}
-
-static int do_proxy_start(client_ctx *cx) {
- conn *incoming;
- conn *outgoing;
-
- incoming = &cx->incoming;
- outgoing = &cx->outgoing;
- ASSERT(incoming->rdstate == c_stop);
- ASSERT(incoming->wrstate == c_done);
- ASSERT(outgoing->rdstate == c_stop);
- ASSERT(outgoing->wrstate == c_stop);
- incoming->wrstate = c_stop;
-
- if (incoming->result < 0) {
- pr_err("write error: %s", uv_strerror(incoming->result));
- return do_kill(cx);
- }
-
- conn_read(incoming);
- conn_read(outgoing);
- return s_proxy;
-}
-
-/* Proxy incoming data back and forth. */
-static int do_proxy(client_ctx *cx) {
- if (conn_cycle("client", &cx->incoming, &cx->outgoing)) {
- return do_kill(cx);
- }
-
- if (conn_cycle("upstream", &cx->outgoing, &cx->incoming)) {
- return do_kill(cx);
- }
-
- return s_proxy;
-}
-
-static int do_kill(client_ctx *cx) {
- int new_state;
-
- if (cx->state >= s_almost_dead_0) {
- return cx->state;
- }
-
- /* Try to cancel the request. The callback still runs but if the
- * cancellation succeeded, it gets called with status=UV_ECANCELED.
- */
- new_state = s_almost_dead_1;
- if (cx->state == s_req_lookup) {
- new_state = s_almost_dead_0;
- uv_cancel(&cx->outgoing.t.req);
- }
-
- conn_close(&cx->incoming);
- conn_close(&cx->outgoing);
- return new_state;
-}
-
-static int do_almost_dead(client_ctx *cx) {
- ASSERT(cx->state >= s_almost_dead_0);
- return cx->state + 1; /* Another finalizer completed. */
-}
-
-static int conn_cycle(const char *who, conn *a, conn *b) {
- if (a->result < 0) {
- if (a->result != UV_EOF) {
- pr_err("%s error: %s", who, uv_strerror(a->result));
- }
- return -1;
- }
-
- if (b->result < 0) {
- return -1;
- }
-
- if (a->wrstate == c_done) {
- a->wrstate = c_stop;
- }
-
- /* The logic is as follows: read when we don't write and write when we don't
- * read. That gives us back-pressure handling for free because if the peer
- * sends data faster than we consume it, TCP congestion control kicks in.
- */
- if (a->wrstate == c_stop) {
- if (b->rdstate == c_stop) {
- conn_read(b);
- } else if (b->rdstate == c_done) {
- conn_write(a, b->t.buf, b->result);
- b->rdstate = c_stop; /* Triggers the call to conn_read() above. */
- }
- }
-
- return 0;
-}
-
-static void conn_timer_reset(conn *c) {
- CHECK(0 == uv_timer_start(&c->timer_handle,
- conn_timer_expire,
- c->idle_timeout,
- 0));
-}
-
-static void conn_timer_expire(uv_timer_t *handle, int status) {
- conn *c;
-
- CHECK(0 == status);
- c = CONTAINER_OF(handle, conn, timer_handle);
- c->result = UV_ETIMEDOUT;
- do_next(c->client);
-}
-
-static void conn_getaddrinfo(conn *c, const char *hostname) {
- struct addrinfo hints;
-
- memset(&hints, 0, sizeof(hints));
- hints.ai_family = AF_UNSPEC;
- hints.ai_socktype = SOCK_STREAM;
- hints.ai_protocol = IPPROTO_TCP;
- CHECK(0 == uv_getaddrinfo(c->client->sx->loop,
- &c->t.addrinfo_req,
- conn_getaddrinfo_done,
- hostname,
- NULL,
- &hints));
- conn_timer_reset(c);
-}
-
-static void conn_getaddrinfo_done(uv_getaddrinfo_t *req,
- int status,
- struct addrinfo *ai) {
- conn *c;
-
- c = CONTAINER_OF(req, conn, t.addrinfo_req);
- c->result = status;
-
- if (status == 0) {
- /* FIXME(bnoordhuis) Should try all addresses. */
- if (ai->ai_family == AF_INET) {
- c->t.addr4 = *(const struct sockaddr_in *) ai->ai_addr;
- } else if (ai->ai_family == AF_INET6) {
- c->t.addr6 = *(const struct sockaddr_in6 *) ai->ai_addr;
- } else {
- UNREACHABLE();
- }
- }
-
- uv_freeaddrinfo(ai);
- do_next(c->client);
-}
-
-/* Assumes that c->t.sa contains a valid AF_INET or AF_INET6 address. */
-static int conn_connect(conn *c) {
- ASSERT(c->t.addr.sa_family == AF_INET ||
- c->t.addr.sa_family == AF_INET6);
- conn_timer_reset(c);
- return uv_tcp_connect(&c->t.connect_req,
- &c->handle.tcp,
- &c->t.addr,
- conn_connect_done);
-}
-
-static void conn_connect_done(uv_connect_t *req, int status) {
- conn *c;
-
- if (status == UV_ECANCELED) {
- return; /* Handle has been closed. */
- }
-
- c = CONTAINER_OF(req, conn, t.connect_req);
- c->result = status;
- do_next(c->client);
-}
-
-static void conn_read(conn *c) {
- ASSERT(c->rdstate == c_stop);
- CHECK(0 == uv_read_start(&c->handle.stream, conn_alloc, conn_read_done));
- c->rdstate = c_busy;
- conn_timer_reset(c);
-}
-
-static void conn_read_done(uv_stream_t *handle,
- ssize_t nread,
- const uv_buf_t *buf) {
- conn *c;
-
- c = CONTAINER_OF(handle, conn, handle);
- ASSERT(c->t.buf == buf->base);
- ASSERT(c->rdstate == c_busy);
- c->rdstate = c_done;
- c->result = nread;
-
- uv_read_stop(&c->handle.stream);
- do_next(c->client);
-}
-
-static void conn_alloc(uv_handle_t *handle, size_t size, uv_buf_t *buf) {
- conn *c;
-
- c = CONTAINER_OF(handle, conn, handle);
- ASSERT(c->rdstate == c_busy);
- buf->base = c->t.buf;
- buf->len = sizeof(c->t.buf);
-}
-
-static void conn_write(conn *c, const void *data, unsigned int len) {
- uv_buf_t buf;
-
- ASSERT(c->wrstate == c_stop || c->wrstate == c_done);
- c->wrstate = c_busy;
-
- /* It's okay to cast away constness here, uv_write() won't modify the
- * memory.
- */
- buf.base = (char *) data;
- buf.len = len;
-
- CHECK(0 == uv_write(&c->write_req,
- &c->handle.stream,
- &buf,
- 1,
- conn_write_done));
- conn_timer_reset(c);
-}
-
-static void conn_write_done(uv_write_t *req, int status) {
- conn *c;
-
- if (status == UV_ECANCELED) {
- return; /* Handle has been closed. */
- }
-
- c = CONTAINER_OF(req, conn, write_req);
- ASSERT(c->wrstate == c_busy);
- c->wrstate = c_done;
- c->result = status;
- do_next(c->client);
-}
-
-static void conn_close(conn *c) {
- ASSERT(c->rdstate != c_dead);
- ASSERT(c->wrstate != c_dead);
- c->rdstate = c_dead;
- c->wrstate = c_dead;
- c->timer_handle.data = c;
- c->handle.handle.data = c;
- uv_close(&c->handle.handle, conn_close_done);
- uv_close((uv_handle_t *) &c->timer_handle, conn_close_done);
-}
-
-static void conn_close_done(uv_handle_t *handle) {
- conn *c;
-
- c = handle->data;
- do_next(c->client);
-}
diff --git a/3rdparty/libuv/samples/socks5-proxy/defs.h b/3rdparty/libuv/samples/socks5-proxy/defs.h
deleted file mode 100644
index 99ee8160c8a..00000000000
--- a/3rdparty/libuv/samples/socks5-proxy/defs.h
+++ /dev/null
@@ -1,139 +0,0 @@
-/* Copyright StrongLoop, Inc. All rights reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
-#ifndef DEFS_H_
-#define DEFS_H_
-
-#include "s5.h"
-#include "uv.h"
-
-#include <assert.h>
-#include <netinet/in.h> /* sockaddr_in, sockaddr_in6 */
-#include <stddef.h> /* size_t, ssize_t */
-#include <stdint.h>
-#include <sys/socket.h> /* sockaddr */
-
-struct client_ctx;
-
-typedef struct {
- const char *bind_host;
- unsigned short bind_port;
- unsigned int idle_timeout;
-} server_config;
-
-typedef struct {
- unsigned int idle_timeout; /* Connection idle timeout in ms. */
- uv_tcp_t tcp_handle;
- uv_loop_t *loop;
-} server_ctx;
-
-typedef struct {
- unsigned char rdstate;
- unsigned char wrstate;
- unsigned int idle_timeout;
- struct client_ctx *client; /* Backlink to owning client context. */
- ssize_t result;
- union {
- uv_handle_t handle;
- uv_stream_t stream;
- uv_tcp_t tcp;
- uv_udp_t udp;
- } handle;
- uv_timer_t timer_handle; /* For detecting timeouts. */
- uv_write_t write_req;
- /* We only need one of these at a time so make them share memory. */
- union {
- uv_getaddrinfo_t addrinfo_req;
- uv_connect_t connect_req;
- uv_req_t req;
- struct sockaddr_in6 addr6;
- struct sockaddr_in addr4;
- struct sockaddr addr;
- char buf[2048]; /* Scratch space. Used to read data into. */
- } t;
-} conn;
-
-typedef struct client_ctx {
- unsigned int state;
- server_ctx *sx; /* Backlink to owning server context. */
- s5_ctx parser; /* The SOCKS protocol parser. */
- conn incoming; /* Connection with the SOCKS client. */
- conn outgoing; /* Connection with upstream. */
-} client_ctx;
-
-/* server.c */
-int server_run(const server_config *cf, uv_loop_t *loop);
-int can_auth_none(const server_ctx *sx, const client_ctx *cx);
-int can_auth_passwd(const server_ctx *sx, const client_ctx *cx);
-int can_access(const server_ctx *sx,
- const client_ctx *cx,
- const struct sockaddr *addr);
-
-/* client.c */
-void client_finish_init(server_ctx *sx, client_ctx *cx);
-
-/* util.c */
-#if defined(__GNUC__)
-# define ATTRIBUTE_FORMAT_PRINTF(a, b) __attribute__((format(printf, a, b)))
-#else
-# define ATTRIBUTE_FORMAT_PRINTF(a, b)
-#endif
-void pr_info(const char *fmt, ...) ATTRIBUTE_FORMAT_PRINTF(1, 2);
-void pr_warn(const char *fmt, ...) ATTRIBUTE_FORMAT_PRINTF(1, 2);
-void pr_err(const char *fmt, ...) ATTRIBUTE_FORMAT_PRINTF(1, 2);
-void *xmalloc(size_t size);
-
-/* main.c */
-const char *_getprogname(void);
-
-/* getopt.c */
-#if !HAVE_UNISTD_H
-extern char *optarg;
-int getopt(int argc, char **argv, const char *options);
-#endif
-
-/* ASSERT() is for debug checks, CHECK() for run-time sanity checks.
- * DEBUG_CHECKS is for expensive debug checks that we only want to
- * enable in debug builds but still want type-checked by the compiler
- * in release builds.
- */
-#if defined(NDEBUG)
-# define ASSERT(exp)
-# define CHECK(exp) do { if (!(exp)) abort(); } while (0)
-# define DEBUG_CHECKS (0)
-#else
-# define ASSERT(exp) assert(exp)
-# define CHECK(exp) assert(exp)
-# define DEBUG_CHECKS (1)
-#endif
-
-#define UNREACHABLE() CHECK(!"Unreachable code reached.")
-
-/* This macro looks complicated but it's not: it calculates the address
- * of the embedding struct through the address of the embedded struct.
- * In other words, if struct A embeds struct B, then we can obtain
- * the address of A by taking the address of B and subtracting the
- * field offset of B in A.
- */
-#define CONTAINER_OF(ptr, type, field) \
- ((type *) ((char *) (ptr) - ((char *) &((type *) 0)->field)))
-
-#endif /* DEFS_H_ */
diff --git a/3rdparty/libuv/samples/socks5-proxy/getopt.c b/3rdparty/libuv/samples/socks5-proxy/getopt.c
deleted file mode 100644
index 8481b2264f2..00000000000
--- a/3rdparty/libuv/samples/socks5-proxy/getopt.c
+++ /dev/null
@@ -1,131 +0,0 @@
-/* $NetBSD: getopt.c,v 1.26 2003/08/07 16:43:40 agc Exp $ */
-
-/*
- * Copyright (c) 1987, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)getopt.c 8.3 (Berkeley) 4/27/95";
-#endif /* LIBC_SCCS and not lint */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-extern const char *_getprogname(void);
-
-int opterr = 1, /* if error message should be printed */
- optind = 1, /* index into parent argv vector */
- optopt, /* character checked for validity */
- optreset; /* reset getopt */
-char *optarg; /* argument associated with option */
-
-#define BADCH (int)'?'
-#define BADARG (int)':'
-#define EMSG ""
-
-/*
- * getopt --
- * Parse argc/argv argument vector.
- */
-int
-getopt(nargc, nargv, ostr)
- int nargc;
- char * const nargv[];
- const char *ostr;
-{
- static char *place = EMSG; /* option letter processing */
- char *oli; /* option letter list index */
-
- if (optreset || *place == 0) { /* update scanning pointer */
- optreset = 0;
- place = nargv[optind];
- if (optind >= nargc || *place++ != '-') {
- /* Argument is absent or is not an option */
- place = EMSG;
- return (-1);
- }
- optopt = *place++;
- if (optopt == '-' && *place == 0) {
- /* "--" => end of options */
- ++optind;
- place = EMSG;
- return (-1);
- }
- if (optopt == 0) {
- /* Solitary '-', treat as a '-' option
- if the program (eg su) is looking for it. */
- place = EMSG;
- if (strchr(ostr, '-') == NULL)
- return (-1);
- optopt = '-';
- }
- } else
- optopt = *place++;
-
- /* See if option letter is one the caller wanted... */
- if (optopt == ':' || (oli = strchr(ostr, optopt)) == NULL) {
- if (*place == 0)
- ++optind;
- if (opterr && *ostr != ':')
- (void)fprintf(stderr,
- "%s: illegal option -- %c\n", _getprogname(),
- optopt);
- return (BADCH);
- }
-
- /* Does this option need an argument? */
- if (oli[1] != ':') {
- /* don't need argument */
- optarg = NULL;
- if (*place == 0)
- ++optind;
- } else {
- /* Option-argument is either the rest of this argument or the
- entire next argument. */
- if (*place)
- optarg = place;
- else if (nargc > ++optind)
- optarg = nargv[optind];
- else {
- /* option-argument absent */
- place = EMSG;
- if (*ostr == ':')
- return (BADARG);
- if (opterr)
- (void)fprintf(stderr,
- "%s: option requires an argument -- %c\n",
- _getprogname(), optopt);
- return (BADCH);
- }
- place = EMSG;
- ++optind;
- }
- return (optopt); /* return option letter */
-}
diff --git a/3rdparty/libuv/samples/socks5-proxy/main.c b/3rdparty/libuv/samples/socks5-proxy/main.c
deleted file mode 100644
index 04020cbd3ad..00000000000
--- a/3rdparty/libuv/samples/socks5-proxy/main.c
+++ /dev/null
@@ -1,99 +0,0 @@
-/* Copyright StrongLoop, Inc. All rights reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
-#include "defs.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#if HAVE_UNISTD_H
-#include <unistd.h> /* getopt */
-#endif
-
-#define DEFAULT_BIND_HOST "127.0.0.1"
-#define DEFAULT_BIND_PORT 1080
-#define DEFAULT_IDLE_TIMEOUT (60 * 1000)
-
-static void parse_opts(server_config *cf, int argc, char **argv);
-static void usage(void);
-
-static const char *progname = __FILE__; /* Reset in main(). */
-
-int main(int argc, char **argv) {
- server_config config;
- int err;
-
- progname = argv[0];
- memset(&config, 0, sizeof(config));
- config.bind_host = DEFAULT_BIND_HOST;
- config.bind_port = DEFAULT_BIND_PORT;
- config.idle_timeout = DEFAULT_IDLE_TIMEOUT;
- parse_opts(&config, argc, argv);
-
- err = server_run(&config, uv_default_loop());
- if (err) {
- exit(1);
- }
-
- return 0;
-}
-
-const char *_getprogname(void) {
- return progname;
-}
-
-static void parse_opts(server_config *cf, int argc, char **argv) {
- int opt;
-
- while (-1 != (opt = getopt(argc, argv, "H:hp:"))) {
- switch (opt) {
- case 'H':
- cf->bind_host = optarg;
- break;
-
- case 'p':
- if (1 != sscanf(optarg, "%hu", &cf->bind_port)) {
- pr_err("bad port number: %s", optarg);
- usage();
- }
- break;
-
- default:
- usage();
- }
- }
-}
-
-static void usage(void) {
- printf("Usage:\n"
- "\n"
- " %s [-b <address> [-h] [-p <port>]\n"
- "\n"
- "Options:\n"
- "\n"
- " -b <hostname|address> Bind to this address or hostname.\n"
- " Default: \"127.0.0.1\"\n"
- " -h Show this help message.\n"
- " -p <port> Bind to this port number. Default: 1080\n"
- "",
- progname);
- exit(1);
-}
diff --git a/3rdparty/libuv/samples/socks5-proxy/s5.c b/3rdparty/libuv/samples/socks5-proxy/s5.c
deleted file mode 100644
index 4f08e345247..00000000000
--- a/3rdparty/libuv/samples/socks5-proxy/s5.c
+++ /dev/null
@@ -1,271 +0,0 @@
-/* Copyright StrongLoop, Inc. All rights reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
-#include "s5.h"
-#include <errno.h>
-#include <stdint.h>
-#include <stdlib.h> /* abort() */
-#include <string.h> /* memset() */
-
-enum {
- s5_version,
- s5_nmethods,
- s5_methods,
- s5_auth_pw_version,
- s5_auth_pw_userlen,
- s5_auth_pw_username,
- s5_auth_pw_passlen,
- s5_auth_pw_password,
- s5_req_version,
- s5_req_cmd,
- s5_req_reserved,
- s5_req_atyp,
- s5_req_atyp_host,
- s5_req_daddr,
- s5_req_dport0,
- s5_req_dport1,
- s5_dead
-};
-
-void s5_init(s5_ctx *cx) {
- memset(cx, 0, sizeof(*cx));
- cx->state = s5_version;
-}
-
-s5_err s5_parse(s5_ctx *cx, uint8_t **data, size_t *size) {
- s5_err err;
- uint8_t *p;
- uint8_t c;
- size_t i;
- size_t n;
-
- p = *data;
- n = *size;
- i = 0;
-
- while (i < n) {
- c = p[i];
- i += 1;
- switch (cx->state) {
- case s5_version:
- if (c != 5) {
- err = s5_bad_version;
- goto out;
- }
- cx->state = s5_nmethods;
- break;
-
- case s5_nmethods:
- cx->arg0 = 0;
- cx->arg1 = c; /* Number of bytes to read. */
- cx->state = s5_methods;
- break;
-
- case s5_methods:
- if (cx->arg0 < cx->arg1) {
- switch (c) {
- case 0:
- cx->methods |= S5_AUTH_NONE;
- break;
- case 1:
- cx->methods |= S5_AUTH_GSSAPI;
- break;
- case 2:
- cx->methods |= S5_AUTH_PASSWD;
- break;
- /* Ignore everything we don't understand. */
- }
- cx->arg0 += 1;
- }
- if (cx->arg0 == cx->arg1) {
- err = s5_auth_select;
- goto out;
- }
- break;
-
- case s5_auth_pw_version:
- if (c != 1) {
- err = s5_bad_version;
- goto out;
- }
- cx->state = s5_auth_pw_userlen;
- break;
-
- case s5_auth_pw_userlen:
- cx->arg0 = 0;
- cx->userlen = c;
- cx->state = s5_auth_pw_username;
- break;
-
- case s5_auth_pw_username:
- if (cx->arg0 < cx->userlen) {
- cx->username[cx->arg0] = c;
- cx->arg0 += 1;
- }
- if (cx->arg0 == cx->userlen) {
- cx->username[cx->userlen] = '\0';
- cx->state = s5_auth_pw_passlen;
- }
- break;
-
- case s5_auth_pw_passlen:
- cx->arg0 = 0;
- cx->passlen = c;
- cx->state = s5_auth_pw_password;
- break;
-
- case s5_auth_pw_password:
- if (cx->arg0 < cx->passlen) {
- cx->password[cx->arg0] = c;
- cx->arg0 += 1;
- }
- if (cx->arg0 == cx->passlen) {
- cx->password[cx->passlen] = '\0';
- cx->state = s5_req_version;
- err = s5_auth_verify;
- goto out;
- }
- break;
-
- case s5_req_version:
- if (c != 5) {
- err = s5_bad_version;
- goto out;
- }
- cx->state = s5_req_cmd;
- break;
-
- case s5_req_cmd:
- switch (c) {
- case 1: /* TCP connect */
- cx->cmd = s5_cmd_tcp_connect;
- break;
- case 3: /* UDP associate */
- cx->cmd = s5_cmd_udp_assoc;
- break;
- default:
- err = s5_bad_cmd;
- goto out;
- }
- cx->state = s5_req_reserved;
- break;
-
- case s5_req_reserved:
- cx->state = s5_req_atyp;
- break;
-
- case s5_req_atyp:
- cx->arg0 = 0;
- switch (c) {
- case 1: /* IPv4, four octets. */
- cx->state = s5_req_daddr;
- cx->atyp = s5_atyp_ipv4;
- cx->arg1 = 4;
- break;
- case 3: /* Hostname. First byte is length. */
- cx->state = s5_req_atyp_host;
- cx->atyp = s5_atyp_host;
- cx->arg1 = 0;
- break;
- case 4: /* IPv6, sixteen octets. */
- cx->state = s5_req_daddr;
- cx->atyp = s5_atyp_ipv6;
- cx->arg1 = 16;
- break;
- default:
- err = s5_bad_atyp;
- goto out;
- }
- break;
-
- case s5_req_atyp_host:
- cx->arg1 = c;
- cx->state = s5_req_daddr;
- break;
-
- case s5_req_daddr:
- if (cx->arg0 < cx->arg1) {
- cx->daddr[cx->arg0] = c;
- cx->arg0 += 1;
- }
- if (cx->arg0 == cx->arg1) {
- cx->daddr[cx->arg1] = '\0';
- cx->state = s5_req_dport0;
- }
- break;
-
- case s5_req_dport0:
- cx->dport = c << 8;
- cx->state = s5_req_dport1;
- break;
-
- case s5_req_dport1:
- cx->dport |= c;
- cx->state = s5_dead;
- err = s5_exec_cmd;
- goto out;
-
- case s5_dead:
- break;
-
- default:
- abort();
- }
- }
- err = s5_ok;
-
-out:
- *data = p + i;
- *size = n - i;
- return err;
-}
-
-unsigned int s5_auth_methods(const s5_ctx *cx) {
- return cx->methods;
-}
-
-int s5_select_auth(s5_ctx *cx, s5_auth_method method) {
- int err;
-
- err = 0;
- switch (method) {
- case S5_AUTH_NONE:
- cx->state = s5_req_version;
- break;
- case S5_AUTH_PASSWD:
- cx->state = s5_auth_pw_version;
- break;
- default:
- err = -EINVAL;
- }
-
- return err;
-}
-
-const char *s5_strerror(s5_err err) {
-#define S5_ERR_GEN(_, name, errmsg) case s5_ ## name: return errmsg;
- switch (err) {
- S5_ERR_MAP(S5_ERR_GEN)
- default: ; /* Silence s5_max_errors -Wswitch warning. */
- }
-#undef S5_ERR_GEN
- return "Unknown error.";
-}
diff --git a/3rdparty/libuv/samples/socks5-proxy/s5.h b/3rdparty/libuv/samples/socks5-proxy/s5.h
deleted file mode 100644
index 715f322287d..00000000000
--- a/3rdparty/libuv/samples/socks5-proxy/s5.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/* Copyright StrongLoop, Inc. All rights reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
-#ifndef S5_H_
-#define S5_H_
-
-#include <stddef.h>
-#include <stdint.h>
-
-#define S5_ERR_MAP(V) \
- V(-1, bad_version, "Bad protocol version.") \
- V(-2, bad_cmd, "Bad protocol command.") \
- V(-3, bad_atyp, "Bad address type.") \
- V(0, ok, "No error.") \
- V(1, auth_select, "Select authentication method.") \
- V(2, auth_verify, "Verify authentication.") \
- V(3, exec_cmd, "Execute command.") \
-
-typedef enum {
-#define S5_ERR_GEN(code, name, _) s5_ ## name = code,
- S5_ERR_MAP(S5_ERR_GEN)
-#undef S5_ERR_GEN
- s5_max_errors
-} s5_err;
-
-typedef enum {
- S5_AUTH_NONE = 1 << 0,
- S5_AUTH_GSSAPI = 1 << 1,
- S5_AUTH_PASSWD = 1 << 2
-} s5_auth_method;
-
-typedef enum {
- s5_auth_allow,
- s5_auth_deny
-} s5_auth_result;
-
-typedef enum {
- s5_atyp_ipv4,
- s5_atyp_ipv6,
- s5_atyp_host
-} s5_atyp;
-
-typedef enum {
- s5_cmd_tcp_connect,
- s5_cmd_tcp_bind,
- s5_cmd_udp_assoc
-} s5_cmd;
-
-typedef struct {
- uint32_t arg0; /* Scratch space for the state machine. */
- uint32_t arg1; /* Scratch space for the state machine. */
- uint8_t state;
- uint8_t methods;
- uint8_t cmd;
- uint8_t atyp;
- uint8_t userlen;
- uint8_t passlen;
- uint16_t dport;
- uint8_t username[257];
- uint8_t password[257];
- uint8_t daddr[257]; /* TODO(bnoordhuis) Merge with username/password. */
-} s5_ctx;
-
-void s5_init(s5_ctx *ctx);
-
-s5_err s5_parse(s5_ctx *cx, uint8_t **data, size_t *size);
-
-/* Only call after s5_parse() has returned s5_want_auth_method. */
-unsigned int s5_auth_methods(const s5_ctx *cx);
-
-/* Call after s5_parse() has returned s5_want_auth_method. */
-int s5_select_auth(s5_ctx *cx, s5_auth_method method);
-
-const char *s5_strerror(s5_err err);
-
-#endif /* S5_H_ */
diff --git a/3rdparty/libuv/samples/socks5-proxy/server.c b/3rdparty/libuv/samples/socks5-proxy/server.c
deleted file mode 100644
index 3f1ba42c9e1..00000000000
--- a/3rdparty/libuv/samples/socks5-proxy/server.c
+++ /dev/null
@@ -1,241 +0,0 @@
-/* Copyright StrongLoop, Inc. All rights reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
-#include "defs.h"
-#include <netinet/in.h> /* INET6_ADDRSTRLEN */
-#include <stdlib.h>
-#include <string.h>
-
-#ifndef INET6_ADDRSTRLEN
-# define INET6_ADDRSTRLEN 63
-#endif
-
-typedef struct {
- uv_getaddrinfo_t getaddrinfo_req;
- server_config config;
- server_ctx *servers;
- uv_loop_t *loop;
-} server_state;
-
-static void do_bind(uv_getaddrinfo_t *req, int status, struct addrinfo *ai);
-static void on_connection(uv_stream_t *server, int status);
-
-int server_run(const server_config *cf, uv_loop_t *loop) {
- struct addrinfo hints;
- server_state state;
- int err;
-
- memset(&state, 0, sizeof(state));
- state.servers = NULL;
- state.config = *cf;
- state.loop = loop;
-
- /* Resolve the address of the interface that we should bind to.
- * The getaddrinfo callback starts the server and everything else.
- */
- memset(&hints, 0, sizeof(hints));
- hints.ai_family = AF_UNSPEC;
- hints.ai_socktype = SOCK_STREAM;
- hints.ai_protocol = IPPROTO_TCP;
-
- err = uv_getaddrinfo(loop,
- &state.getaddrinfo_req,
- do_bind,
- cf->bind_host,
- NULL,
- &hints);
- if (err != 0) {
- pr_err("getaddrinfo: %s", uv_strerror(err));
- return err;
- }
-
- /* Start the event loop. Control continues in do_bind(). */
- if (uv_run(loop, UV_RUN_DEFAULT)) {
- abort();
- }
-
- /* Please Valgrind. */
- uv_loop_delete(loop);
- free(state.servers);
- return 0;
-}
-
-/* Bind a server to each address that getaddrinfo() reported. */
-static void do_bind(uv_getaddrinfo_t *req, int status, struct addrinfo *addrs) {
- char addrbuf[INET6_ADDRSTRLEN + 1];
- unsigned int ipv4_naddrs;
- unsigned int ipv6_naddrs;
- server_state *state;
- server_config *cf;
- struct addrinfo *ai;
- const void *addrv;
- const char *what;
- uv_loop_t *loop;
- server_ctx *sx;
- unsigned int n;
- int err;
- union {
- struct sockaddr addr;
- struct sockaddr_in addr4;
- struct sockaddr_in6 addr6;
- } s;
-
- state = CONTAINER_OF(req, server_state, getaddrinfo_req);
- loop = state->loop;
- cf = &state->config;
-
- if (status < 0) {
- pr_err("getaddrinfo(\"%s\"): %s", cf->bind_host, uv_strerror(status));
- uv_freeaddrinfo(addrs);
- return;
- }
-
- ipv4_naddrs = 0;
- ipv6_naddrs = 0;
- for (ai = addrs; ai != NULL; ai = ai->ai_next) {
- if (ai->ai_family == AF_INET) {
- ipv4_naddrs += 1;
- } else if (ai->ai_family == AF_INET6) {
- ipv6_naddrs += 1;
- }
- }
-
- if (ipv4_naddrs == 0 && ipv6_naddrs == 0) {
- pr_err("%s has no IPv4/6 addresses", cf->bind_host);
- uv_freeaddrinfo(addrs);
- return;
- }
-
- state->servers =
- xmalloc((ipv4_naddrs + ipv6_naddrs) * sizeof(state->servers[0]));
-
- n = 0;
- for (ai = addrs; ai != NULL; ai = ai->ai_next) {
- if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) {
- continue;
- }
-
- if (ai->ai_family == AF_INET) {
- s.addr4 = *(const struct sockaddr_in *) ai->ai_addr;
- s.addr4.sin_port = htons(cf->bind_port);
- addrv = &s.addr4.sin_addr;
- } else if (ai->ai_family == AF_INET6) {
- s.addr6 = *(const struct sockaddr_in6 *) ai->ai_addr;
- s.addr6.sin6_port = htons(cf->bind_port);
- addrv = &s.addr6.sin6_addr;
- } else {
- UNREACHABLE();
- }
-
- if (uv_inet_ntop(s.addr.sa_family, addrv, addrbuf, sizeof(addrbuf))) {
- UNREACHABLE();
- }
-
- sx = state->servers + n;
- sx->loop = loop;
- sx->idle_timeout = state->config.idle_timeout;
- CHECK(0 == uv_tcp_init(loop, &sx->tcp_handle));
-
- what = "uv_tcp_bind";
- err = uv_tcp_bind(&sx->tcp_handle, &s.addr, 0);
- if (err == 0) {
- what = "uv_listen";
- err = uv_listen((uv_stream_t *) &sx->tcp_handle, 128, on_connection);
- }
-
- if (err != 0) {
- pr_err("%s(\"%s:%hu\"): %s",
- what,
- addrbuf,
- cf->bind_port,
- uv_strerror(err));
- while (n > 0) {
- n -= 1;
- uv_close((uv_handle_t *) (state->servers + n), NULL);
- }
- break;
- }
-
- pr_info("listening on %s:%hu", addrbuf, cf->bind_port);
- n += 1;
- }
-
- uv_freeaddrinfo(addrs);
-}
-
-static void on_connection(uv_stream_t *server, int status) {
- server_ctx *sx;
- client_ctx *cx;
-
- CHECK(status == 0);
- sx = CONTAINER_OF(server, server_ctx, tcp_handle);
- cx = xmalloc(sizeof(*cx));
- CHECK(0 == uv_tcp_init(sx->loop, &cx->incoming.handle.tcp));
- CHECK(0 == uv_accept(server, &cx->incoming.handle.stream));
- client_finish_init(sx, cx);
-}
-
-int can_auth_none(const server_ctx *sx, const client_ctx *cx) {
- return 1;
-}
-
-int can_auth_passwd(const server_ctx *sx, const client_ctx *cx) {
- return 0;
-}
-
-int can_access(const server_ctx *sx,
- const client_ctx *cx,
- const struct sockaddr *addr) {
- const struct sockaddr_in6 *addr6;
- const struct sockaddr_in *addr4;
- const uint32_t *p;
- uint32_t a;
- uint32_t b;
- uint32_t c;
- uint32_t d;
-
- /* TODO(bnoordhuis) Implement proper access checks. For now, just reject
- * traffic to localhost.
- */
- if (addr->sa_family == AF_INET) {
- addr4 = (const struct sockaddr_in *) addr;
- d = ntohl(addr4->sin_addr.s_addr);
- return (d >> 24) != 0x7F;
- }
-
- if (addr->sa_family == AF_INET6) {
- addr6 = (const struct sockaddr_in6 *) addr;
- p = (const uint32_t *) &addr6->sin6_addr.s6_addr;
- a = ntohl(p[0]);
- b = ntohl(p[1]);
- c = ntohl(p[2]);
- d = ntohl(p[3]);
- if (a == 0 && b == 0 && c == 0 && d == 1) {
- return 0; /* "::1" style address. */
- }
- if (a == 0 && b == 0 && c == 0xFFFF && (d >> 24) == 0x7F) {
- return 0; /* "::ffff:127.x.x.x" style address. */
- }
- return 1;
- }
-
- return 0;
-}
diff --git a/3rdparty/libuv/samples/socks5-proxy/util.c b/3rdparty/libuv/samples/socks5-proxy/util.c
deleted file mode 100644
index af34f055936..00000000000
--- a/3rdparty/libuv/samples/socks5-proxy/util.c
+++ /dev/null
@@ -1,72 +0,0 @@
-/* Copyright StrongLoop, Inc. All rights reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
-#include "defs.h"
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-static void pr_do(FILE *stream,
- const char *label,
- const char *fmt,
- va_list ap);
-
-void *xmalloc(size_t size) {
- void *ptr;
-
- ptr = malloc(size);
- if (ptr == NULL) {
- pr_err("out of memory, need %lu bytes", (unsigned long) size);
- exit(1);
- }
-
- return ptr;
-}
-
-void pr_info(const char *fmt, ...) {
- va_list ap;
- va_start(ap, fmt);
- pr_do(stdout, "info", fmt, ap);
- va_end(ap);
-}
-
-void pr_warn(const char *fmt, ...) {
- va_list ap;
- va_start(ap, fmt);
- pr_do(stderr, "warn", fmt, ap);
- va_end(ap);
-}
-
-void pr_err(const char *fmt, ...) {
- va_list ap;
- va_start(ap, fmt);
- pr_do(stderr, "error", fmt, ap);
- va_end(ap);
-}
-
-static void pr_do(FILE *stream,
- const char *label,
- const char *fmt,
- va_list ap) {
- char fmtbuf[1024];
- vsnprintf(fmtbuf, sizeof(fmtbuf), fmt, ap);
- fprintf(stream, "%s:%s: %s\n", _getprogname(), label, fmtbuf);
-}