コード例 #1
0
ファイル: ddclsocket.c プロジェクト: diandian-xue/ddengine
static void
_excute_read_cmd(SocketCmd * cmd, ddcl_Service source, ddcl_Session session){
    ddcl_Socket h = cmd->h;
    Socket * s = _find_socket(h);
    if(!s || s->fd != cmd->fd){
        const char * err = "socket fd error";
        ddcl_send_b(source, 0, DDCL_PTYPE_RESP,
            DDCL_CMD_ERROR, session, err, strlen(err) + 1);
        return;
    }
    if(s->forward){
        const char * err = "socket fd is forward mode";
        ddcl_send_b(source, 0, DDCL_PTYPE_RESP,
            DDCL_CMD_ERROR, session, err, strlen(err) + 1);
        return;
    }


    size_t sz = cmd->sz;
    if(!_read_buff_is_empty(s)){
        _push_read_buff(s, cmd->sz, source, session);
        _add_evt_2_poll(s->st->poll, s, DDSOCKETPOLL_READ);
        return;
    }

    size_t rlen = 0;
    char * rbuf;
    for(;;){
        if(s->cbuf_sz > 0 && s->cbuf_sz >= sz){
            if(sz == 0)
                sz = s->cbuf_sz;
            _rsp_read(s->st->svr, s->h, source, session,
                DDCL_SOCKET_READ, _read_cache_buff(s, sz), sz);
            return;
        }
        if (sz == 0)
            rlen = DEFAULT_RECV_SIZE;
        else
            rlen = sz - s->cbuf_sz;
        if(rlen <= DEFAULT_RECV_SIZE)
            rbuf = s->crbuf;
        else
            rbuf = ddcl_malloc(rlen);

        int rsz = recv(s->fd, rbuf, (int)rlen, 0);
        if(rsz > 0){
            _push_cache_buff(s, rbuf, rsz, rlen <= DEFAULT_RECV_SIZE);
            if(rlen > DEFAULT_RECV_SIZE)
                ddcl_free(rbuf);
        }else{
            if(rlen > DEFAULT_RECV_SIZE)
                ddcl_free(rbuf);
            break;
        }
    }

    _push_read_buff(s, sz, source, session);
    if(!(s->poll_evt & DDSOCKETPOLL_READ))
        _add_evt_2_poll(s->st->poll, s, DDSOCKETPOLL_READ);
}
コード例 #2
0
ファイル: ddclsocket.c プロジェクト: diandian-xue/ddengine
static void
_execute_event(SocketThread * st, ddcl_Socket h, int evt){
    Socket * s = _find_socket(h);
    if(!s)
        return;
    switch(s->status){
    case _SS_CONNECTING:
        _execute_event_in_fd_connecting(st, s, evt);
        break;
    case _SS_CONNECTED:
        _execute_event_on_fd_connected(st, s, evt);
        break;
    case _SS_LISTENING:
        _execute_event_on_fd_listening(st, s, evt);
        break;
        /*
    case _SS_CLOSE:
        _execute_event_in_fd_close(st, s, evt);
        break;
        */
    default:
        assert(0);
        break;
    }
}
コード例 #3
0
ファイル: ddclsocket.c プロジェクト: diandian-xue/ddengine
static void
_excute_send_cmd(SocketCmd * cmd, ddcl_Service source, ddcl_Session session){
    ddcl_Socket h = cmd->h;
    Socket * s = _find_socket(h);
    if(!s || s->fd != cmd->fd){
        return;
    }
    char * buf = cmd->data;
    size_t sz = cmd->sz;
    size_t slen = 0;
    if(_send_buff_is_empty(s)){
        int n;
        for(;;){
            n = send(s->fd, buf + slen, (int)(sz - slen), 0);
            if(n <= 0)
                break;
            slen += n;
            if (slen >= sz) {
                ddcl_free(cmd->data);
                return;
            }
        }
    }

    _push_send_buff(s, buf + slen, sz - slen);
    _add_evt_2_poll(s->st->poll, s, DDSOCKETPOLL_WRITE);
    ddcl_free(cmd->data);
}
コード例 #4
0
ファイル: ddclsocket.c プロジェクト: diandian-xue/ddengine
static void
_excute_close_cmd(SocketCmd * cmd, ddcl_Service source, ddcl_Session session){
    Socket * s = _find_socket(cmd->h);
    if(s && s->fd == cmd->fd){
        _del_fd(s);
    }
}
コード例 #5
0
ファイル: vsocket.cpp プロジェクト: martinvolk/GlobalNet
int recv(VSOCKET socket, char *data, size_t size) {
    LOCK(mu,0);
    shared_ptr<Node> con = _find_socket(socket);
    if(con) {
        return con->recv(data, size);
    }
    return -1;
}
コード例 #6
0
ファイル: vsocket.cpp プロジェクト: martinvolk/GlobalNet
bool getsockopt(VSOCKET sock, const string &option, string &dst) {
    LOCK(mu,0);
    shared_ptr<Node> n = _find_socket(sock);
    if(n) {
        return n->get_option(option, dst);
    }
    return false;
}
コード例 #7
0
ファイル: vsocket.cpp プロジェクト: martinvolk/GlobalNet
int connect(VSL::VSOCKET socket, const list<URL> &peers) {
    LOCK(mu,0);
    shared_ptr<Node> tun = _find_socket(socket);
    if(tun) tun.reset();
    tun = net->createTunnel(peers);
    sockets[socket] = tun;
    return 0;
}
コード例 #8
0
ファイル: ddclsocket.c プロジェクト: diandian-xue/ddengine
static void
_excute_forward_cmd (SocketCmd * cmd, ddcl_Service source, ddcl_Session session){
    ddcl_Socket h = cmd->h;
    Socket * s = _find_socket(cmd->h);
    if(!s || s->fd != cmd->fd){
        return;
    }
    s->forward = 1;
    _add_evt_2_poll(s->st->poll, s, DDSOCKETPOLL_READ | DDSOCKETPOLL_ERROR);
}
コード例 #9
0
ファイル: vsocket.cpp プロジェクト: martinvolk/GlobalNet
int connect(VSOCKET socket, const URL &url) {
    LOCK(mu,0);
    shared_ptr<Node> con = _find_socket(socket);
    if(con) {
        con->close();
        con.reset();
    }
    con = net->connect(url);
    sockets[socket] = con;
    return 0;
}
コード例 #10
0
ファイル: vsocket.cpp プロジェクト: martinvolk/GlobalNet
int bind(VSOCKET socket, const URL &url) {
    LOCK(mu,0);
    shared_ptr<Node> con = _find_socket(socket);
    if(!con)
        con = net->createNode(url.protocol());
    if(con) {
        sockets[socket] = con;
        return con->bind(url);
    }
    return -1;
}
コード例 #11
0
ファイル: vsocket.cpp プロジェクト: martinvolk/GlobalNet
VSL::VSOCKET accept(VSL::VSOCKET socket) {
    LOCK(mu,0);
    shared_ptr<Node> con = _find_socket(socket);
    if(con) {
        unique_ptr<Node> client = con->accept();
        if(client) {
            VSOCKET s = _create_socket();
            sockets[s] = move(client);
            return s;
        }
        return 0; // listening but no connection
    }
    return -1; // invalid descriptor
}
コード例 #12
0
ファイル: ddclsocket.c プロジェクト: diandian-xue/ddengine
DDCLAPI int
ddcl_forward_socket (ddcl_Socket fd, ddcl_Service from){
    Socket * s = _find_socket(fd);
    if (!s)
        return DDCLSOCKET_INVALID_HANDLE;

    SocketCmd cmd;
    cmd.cmd = _SCMD_FORWARD;
    cmd.h = fd;
    cmd.fd = s->fd;
    SocketThread * st = _st_find(fd);
    ddcl_send_b(st->svr, from, DDCL_PTYPE_SEND,
        DDCL_CMD_SOCKET, 0, (char *)&cmd, sizeof(SocketCmd));
    return DDCL_OK;
}
コード例 #13
0
ファイル: ddclsocket.c プロジェクト: diandian-xue/ddengine
DDCLAPI int
ddcl_read_socket(ddcl_Socket fd, ddcl_Service from, size_t sz, ddcl_Session * session){
    Socket * s = _find_socket(fd);
    if (!s)
        return DDCLSOCKET_INVALID_HANDLE;

    SocketCmd cmd;
    cmd.cmd = _SCMD_READ;
    cmd.h = fd;
    cmd.fd = s->fd;
    cmd.sz = sz;
    SocketThread * st = _st_find(fd);
    ddcl_call_b(st->svr, from, DDCL_PTYPE_SEND, 
        DDCL_CMD_SOCKET, session, (char *)&cmd, sizeof(cmd));

    return DDCL_OK;
}
コード例 #14
0
ファイル: vsocket.cpp プロジェクト: martinvolk/GlobalNet
int getsockinfo(VSOCKET sock, SOCKINFO *info) {
    LOCK(mu,0);
    shared_ptr<Node> n = _find_socket(sock);
    if(!n) return -1;
    if(n->state & CON_STATE_CONNECTING)
        info->state = VSOCKET_CONNECTING;
    else if(n->state & CON_STATE_CONNECTED)
        info->state = VSOCKET_CONNECTED;
    else if(n->state & CON_STATE_DISCONNECTED)
        info->state = VSOCKET_DISCONNECTED;
    else if(n->state & CON_STATE_IDLE)
        info->state = VSOCKET_IDLE;
    else if(n->state & CON_STATE_LISTENING)
        info->state = VSOCKET_LISTENING;

    info->is_connected = (n->state & CON_STATE_CONNECTED) != 0;
    return 0;
}
コード例 #15
0
ファイル: ddclsocket.c プロジェクト: diandian-xue/ddengine
static void
_excute_accept_cmd(SocketCmd * cmd, ddcl_Service source, ddcl_Session session){
    ddcl_Socket h = cmd->h;
    Socket * s = _find_socket(cmd->h);
    if(!s || s->fd != cmd->fd){
        const char * err = "unknow listen fd for accepting";
        ddcl_send_b(source, 0, DDCL_PTYPE_RESP,
            DDCL_CMD_ERROR, session, err, strlen(err) + 1);
        return;
    }
    if(s->forward){
        const char * err = "socket fd is forward mode";
        ddcl_send_b(source, 0, DDCL_PTYPE_RESP,
            DDCL_CMD_ERROR, session, err, strlen(err) + 1);
        return;
    }

    if(!_read_buff_is_empty(s)){
        _push_read_buff(s, cmd->sz, source, session);
        _add_evt_2_poll(s->st->poll, s, DDSOCKETPOLL_READ | DDSOCKETPOLL_ERROR);
        return;
    }

    SockAddrAll saa;
    socklen_t len = sizeof(SockAddrAll);
    DDSOCK_FD fd = accept(s->fd, &(saa.s), &len);
    if(fd != -1){
        _set_keepalive(fd);
        _set_non_blocking(fd);
        Socket *ns = _register_fd(fd, _SS_CONNECTED);
        ns->source = s->source;
        ns->session = s->session;
        _add_in_poll(ns->h, ns, DDSOCKETPOLL_ERROR);
        ns->poll_evt = DDSOCKETPOLL_ERROR;
        _rsp_socket(ns->st, ns, source, session, DDCL_SOCKET_ACCEPT);
    }else{
        _push_read_buff(s, 0, source, session);
        if(!(s->poll_evt & DDSOCKETPOLL_READ))
            _add_evt_2_poll(s->st->poll, s, DDSOCKETPOLL_READ);
    }

}
コード例 #16
0
ファイル: ddclsocket.c プロジェクト: diandian-xue/ddengine
DDCLAPI int
ddcl_send_socket(ddcl_Socket fd, ddcl_Service from, const void * buf, size_t sz){
    Socket * s = _find_socket(fd);
    if(!s)
        return DDCLSOCKET_INVALID_HANDLE;

    SocketCmd cmd;
    cmd.cmd = _SCMD_SEND;
    cmd.h = fd;
    cmd.fd = s->fd;
    cmd.sz = sz;
    cmd.data = ddcl_malloc(sz);
    memcpy(cmd.data, buf, sz);

    SocketThread * st = _st_find(fd);
    ddcl_send_b(st->svr, from, DDCL_PTYPE_SEND,
        DDCL_CMD_SOCKET, 0, (char *)&cmd, sizeof(SocketCmd));

    return DDCL_OK;
}
コード例 #17
0
ファイル: vsocket.cpp プロジェクト: martinvolk/GlobalNet
int listen(VSOCKET socket, const list<URL> &url) {
    LOCK(mu,0);
    shared_ptr<Node> tun = _find_socket(socket);
    if(tun) tun.reset();

    if(url.size() > 1) {
        tun = net->createTunnel(list<URL>(url.begin(), std::prev(url.end())));
        URL u = *(std::prev(url.end()));
        LOG(3, "VSL: attempting to listen remotely on "<<u.url());
        tun->listen(u);
    }
    else {
        URL u = (*url.begin());
        tun = net->createNode(u.protocol());
        if(tun) {
            LOG(3, "VSL: attempting to listen on "<<u.url());
            tun->listen(u);
        }
    }
    sockets[socket] = tun;
    return -1;
}