UniEvent-Socks

 view release on metacpan or  search on metacpan

clib/tests/socks.cc  view on Meta::CPAN

static TcpSP make_socks_server (const LoopSP& loop, const SockAddr& sa) {
    auto server = make_basic_server(loop, sa);
    server->connection_event.add([](auto server, auto stream, auto& err) {
        if (err) throw err;
        std::shared_ptr<int> state = std::make_shared<int>(0);

        TcpSP client = new Tcp(server->loop());
        client->read_event.add([stream](auto, auto& buf, auto& err) {
            if (err) throw err;
            // read from remote server
            stream->write(buf);
        });
        client->eof_event.add([stream](auto) mutable {
            stream->shutdown();
        });
        client->write_event.add([](auto, auto& err, auto) { if (err) throw err; });

        stream->read_event.add([client, state](auto stream, auto& buf, auto&err) {
            panda_rlog_debug("buf = " << buf);
            if (err) throw err;
            switch (*state) {
                case 0: {
                    stream->write("\x05\x00");
                    *state = 1;
                    break;
                }
                case 1: {
                    string request_type = buf.substr(0, 4);
                    if (request_type == string("\x05\x01\x00\x03")) {
                        int host_length = buf[4];
                        string host = buf.substr(5, host_length);
                        uint16_t port = ntohs(*(uint16_t*)buf.substr(5 + host_length).data());
                        client->connect("127.0.0.1", port);
                        client->connect_event.add([](auto, auto& err, auto){ if (err) throw err; });
                    } else {
                        throw std::runtime_error("bad request");
                    }

                    stream->write("\x05\x00\x00\x01\xFF\xFF\xFF\xFF\xFF\xFF");
                    *state = 2;
                    break;
                }
                case 2: {
                    // write to remote server
                    client->write(buf);
                    break;
                }
            }
        });
    });

    return server;
}

static SSL_CTX* get_ssl_ctx () {
    static SSL_CTX* ctx = nullptr;
    if (ctx) return ctx;
    ctx = SSL_CTX_new(SSLv23_server_method());
    SSL_CTX_use_certificate_file(ctx, "tests/cert/cert.pem", SSL_FILETYPE_PEM);
    SSL_CTX_use_PrivateKey_file(ctx, "tests/cert/key.pem", SSL_FILETYPE_PEM);
    SSL_CTX_check_private_key(ctx);
    return ctx;
}



( run in 2.271 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )