Пример #1
0
void
server_mc_read_cb(struct bufferevent *bev, void *ctx)
{
    struct server *s = (struct server *)ctx;
    struct evbuffer *in = bufferevent_get_input(bev);
    struct mc       *mc = v_mc_find_if(s->peers, (void *)find_bev, bev);
    size_t len;
    char *line;

    /* Do nothing: this peer seems to exists, but we didn't approve it yet*/
    if (mc == v_mc_end(s->peers))
        return ;

    while ((line = evbuffer_readln(in, &len, EVBUFFER_EOL_CRLF)) != NULL)
    {
        struct vector_cptr *splited;
        char *cmd_name;

        log_debug("[META] [%s]", line);
        splited = split(line);
        cmd_name = v_cptr_at(splited, 0);
        if (strncmp(cmd_name, "udp_port", strlen(cmd_name)) == 0)
        {
            char            *s_udp_port = v_cptr_at(splited, 1);
            unsigned short  port = atoi(s_udp_port);
            struct endpoint udp_remote_endpoint;

            endpoint_init(&udp_remote_endpoint,
                          mc->p.address,
                          mc->p.len);

            endpoint_set_port(&udp_remote_endpoint, port);

            udp_register_new_peer(s->udp,
                                  &udp_remote_endpoint,
                                  DTLS_DISABLE);
        }
        v_cptr_delete(splited);
        free(line);
    }
}
Пример #2
0
// Housekeeping for URLs
url_t* url_init(url_t *target) {
	if (!mutable_string_init(&(target->url))) {
		return NULL;
	}

	if (!endpoint_init(&(target->endpoint))) {
		return NULL;
	}

	if (!uri_init(&(target->uri))) {
		return NULL;
	}

	if (!qs_init(&(target->query_string))) {
		return NULL;
	}

	target->proto_scheme = HTTP;

	return target;
}
Пример #3
0
int
server_init(struct server *s, struct event_base *evbase)
{
    struct cfg_sockaddress *it_listen = NULL;
    struct cfg_sockaddress *ite_listen = NULL;
    struct cfg_sockaddress *it_client = NULL;
    struct cfg_sockaddress *ite_client = NULL;
    struct cfg_sockaddress *it_peer = NULL;
    struct cfg_sockaddress *ite_peer = NULL;
    size_t i = 0;

    s->peers = v_mc_new();
    s->pending_peers = v_mc_new();
    s->srv_list = v_evl_new();
    s->frames_to_send = v_frame_new();
    s->evbase = evbase;

    it_listen = v_sockaddr_begin(serv_opts.listen_addrs);
    ite_listen = v_sockaddr_end(serv_opts.listen_addrs);
    s->ev_sched = sched_new(evbase);

    /* Listen on all ListenAddress */
    for (; it_listen != ite_listen; it_listen = v_sockaddr_next(it_listen), ++i)
    {
        struct evconnlistener *evl = NULL;
        char listenname[INET6_ADDRSTRLEN];
        struct endpoint endp;

        evl = evconnlistener_new_bind(evbase, listen_callback,
            s, LEV_OPT_CLOSE_ON_FREE | LEV_OPT_REUSEABLE, -1,
            (struct sockaddr *)&it_listen->sockaddr, it_listen->len);
        if (evl == NULL) {
            log_warnx("[INIT] failed to allocate the listener to listen to %s",
                address_presentation((struct sockaddr *)&it_listen->sockaddr,
                it_listen->len, listenname, sizeof listenname));
             continue;
        }
        evconnlistener_set_error_cb(evl, NULL);
        evconnlistener_disable(evl);

        /* udp endpoint init */

        /*
         * We listen on the same address for the udp socket
         */
        endpoint_init(&endp, (struct sockaddr *)&it_listen->sockaddr,
                      it_listen->len);
        s->udp = server_udp_new(s, &endp);
        if (s->udp == NULL)
        {
            log_warnx("[INIT] [UDP] failed to init the udp socket on %s",
                  address_presentation((struct sockaddr *)&it_listen->sockaddr,
                                           it_listen->len, listenname,
                                           sizeof listenname));
            continue;
        }

        v_evl_push(s->srv_list, evl);
    }

	// Listen enable for client in the ports registered
    it_client = v_sockaddr_begin(serv_opts.client_addrs);
    ite_client = v_sockaddr_end(serv_opts.client_addrs);

#ifdef USE_TCLT
    /* Listen on all ClientAddress */
    for (; it_client != ite_client; it_client = v_sockaddr_next(it_client), ++i)
    {
        char clientname[INET6_ADDRSTRLEN];
        struct evconnlistener *evl = NULL;
		evl = evconnlistener_new_bind(evbase, listen_client_callback,
			  s, LEV_OPT_CLOSE_ON_FREE | LEV_OPT_REUSEABLE, -1,
		  (struct sockaddr *)&it_client->sockaddr, it_client->len);
		if (evl == NULL) {
			log_warnx("[INIT] [TCP] failed to allocate the listener to listen to %s",
			  address_presentation((struct sockaddr *)
				&it_client->sockaddr, it_client->len, clientname,
				sizeof clientname));
			continue;
		}
		evconnlistener_set_error_cb(evl, NULL);
		evconnlistener_enable(evl);
		v_evl_push(s->srv_list, evl);
	}
#endif

    /* If we don't have any PeerAddress it's finished */
    if (v_sockaddr_size(serv_opts.peer_addrs) == 0)
        return 0;

    it_peer = v_sockaddr_begin(serv_opts.peer_addrs);
    ite_peer = v_sockaddr_end(serv_opts.peer_addrs);
    for (;it_peer != ite_peer; it_peer = v_sockaddr_next(it_peer))
    {
        struct mc *mc_peer = NULL;
#ifdef USE_TCLT
        peer p;
        char *cmd;

        /* TODO : Real information */
        p.name = strdup("");
        p.name = strdup("");
        p.name = strdup("");
#endif
        mc_peer = mc_peer_connect(s, evbase,
                        (struct sockaddr *)&it_peer->sockaddr,
                        it_peer->len);
#ifdef USE_TCLT
        if (mc_peer != NULL && s->mc_client.bev)
        {
            cmd = tclt_add_peer(&p);
            bufferevent_write(s->mc_client.bev, cmd, strlen(cmd));
            free(cmd);
        }
#endif
    }
    return 0;
}
Пример #4
0
void
server_mc_event_cb(struct bufferevent *bev, short events, void *ctx)
{
    struct server *s = (struct server *)ctx;

    dump_flags(events);
    if (events & BEV_EVENT_CONNECTED)
    {
        struct mc *mc;

        /*
         * If we received the notification that the connection is established,
         * then we move the corresponding struct mc from s->pending_peers to
         * s->peers.
         */

        mc = v_mc_find_if(s->pending_peers, (void *)find_bev, bev);
        if (mc != v_mc_end(s->pending_peers))
        {
            struct mc tmp;
            struct endpoint e;

            endpoint_init(&e, mc->p.address, mc->p.len);
            /* Check for certificate */
            if (mc->ssl_flags & TLS_ENABLE)
            {
                X509 *cert;
                SSL *ssl;
                EVP_PKEY *pubkey;
                char name[512];

                ssl = bufferevent_openssl_get_ssl(mc->bev);
                cert = SSL_get_peer_certificate(ssl);
                if (cert == NULL)
                {
                    log_info("[META] [TLS] %s doesn't share it's certificate.",
                             mc_presentation(mc, name, sizeof name));
                    v_mc_erase(s->pending_peers, mc);
                    mc_close(mc);
                    return ;
                }
                pubkey = X509_get_pubkey(cert); //UNUSED ?
            }
            log_info("[META] [%s] connexion established with %s",
                     mc->ssl_flags & TLS_ENABLE ? "TLS" : "TCP",
                     endpoint_presentation(&e));
            memcpy(&tmp, mc, sizeof(tmp));
            v_mc_erase(s->pending_peers, mc);
            mc = v_mc_insert(s->peers, &tmp);
            mc_hello(mc, s->udp);
            mc_establish_tunnel(mc, s->udp);
        }
    }
    else if (events & BEV_EVENT_EOF)
    {
        /* Disconnected */
        struct mc *mc;
        struct udp_peer *up;

        mc = v_mc_find_if(s->peers, (void *)find_bev, bev);
        if (mc != v_mc_end(s->peers))
        {
            char name[INET6_ADDRSTRLEN];
            struct sockaddr *sock = mc->p.address;

            up = v_udp_find_if(s->udp->udp_peers, find_udppeer, sock);
            if (up != v_udp_end(s->udp->udp_peers))
            {
                v_udp_erase(s->udp->udp_peers, up);
                log_debug("[%s] stop peering with %s",
                          (up->ssl_flags & DTLS_ENABLE) ? "DTLS" : "UDP",
                          endpoint_presentation(&up->peer_addr));
            }
            log_debug("[META] stop the meta-connexion with %s",
                      mc_presentation(mc, name, sizeof(name)));
            mc_close(mc);
            v_mc_erase(s->peers, mc);
        }

    }
    else if (events & BEV_EVENT_ERROR)
    {
        struct mc *mc;
        int everr;
        int sslerr;

        everr = EVUTIL_SOCKET_ERROR();

        if (everr != 0)
        {
            log_warnx("[META] unexpected shutdown of the meta-connexion: (%d) %s",
                       everr, evutil_socket_error_to_string(everr));
        }
        while ((sslerr = bufferevent_get_openssl_error(bev)) != 0)
        {
            log_warnx("[META] SSL error code (%d): %s in %s %s",
                       sslerr, ERR_reason_error_string(sslerr),
                       ERR_lib_error_string(sslerr),
                       ERR_func_error_string(sslerr));
        }
        /*
         * Find if the exception come from a pending peer or a
         * regular peer and close it.
         */
        mc = v_mc_find_if(s->pending_peers, (void *)find_bev, bev);
        if (mc != v_mc_end(s->pending_peers))
        {
            char name[128];

            log_debug("[META] %s removed from the pending list",
                      mc_presentation(mc, name, sizeof name));
            mc_close(mc);
            v_mc_erase(s->pending_peers, mc);
        }
        else
        {
            mc = v_mc_find_if(s->peers, (void *)find_bev, bev);
            if (mc != v_mc_end(s->peers))
            {
                mc_close(mc);
                v_mc_erase(s->peers, mc);
                log_debug("[META] socket removed from the peer list");
            }
        }
    }
}