Пример #1
0
static int socks5_src_choose_auth_method(struct sserver_handle *handle, struct ssession *session) {
    
    // 1. parse
    // 2. clear buf;
    // 3. add response to sendbuf;
    // 4. add fd to writefds
    // 5. set session state to SSESSION_STATE_CONNECT
    
    char ver = 0;
    char nmethod = 0;
    char selmethod = 0x00;
    char methods[256] = {0x00};
    int nread = 0;
    
    struct ringbuffer_tran tran;
    struct ringbuffer *tranrb = NULL;
    
    tranrb = ringbuffer_transaction_begin(session->dstbuf, &tran);
    
    nread = ringbuffer_transaction_read(tranrb, &ver, 1);
    if(nread <= 0) {
        ringbuffer_transaction_rollback(session->dstbuf, &tran);
        return SE_NEEDMORE;
    }
    
    if(ver != 0x5) {
        return SE_UNSUPPORT_VERSION;
    }
    
    nread = ringbuffer_transaction_read(tranrb, &nmethod, 1);
    if(nread <= 0) {
        ringbuffer_transaction_rollback(session->dstbuf, &tran);
        return SE_NEEDMORE;
    }
    
    if(nmethod == 0) {
        return SE_NO_METHOD;
    }
    
    nread = ringbuffer_transaction_read(tranrb, &methods, nmethod);
    if(nread <= 0 && nread != (int) nmethod) {
        ringbuffer_transaction_rollback(session->dstbuf, &tran);
        return SE_NEEDMORE;
    }
    
    ringbuffer_clear(session->dstbuf);
    ringbuffer_write(session->srcbuf, &ver, 1);
    ringbuffer_write(session->srcbuf, &selmethod, 1);
    
    FD_SET(session->srcfd, &handle->server->writefds);
    
    session->state = SSESSION_STATE_CONNECT;
    
    return 0;
}
Пример #2
0
int
ringbuffer_init(RingBuffer **rb, int size, size_t elem_size)
{
    void *ptr =NULL;

    ptr = calloc(1, sizeof(RingBuffer) + (size * elem_size));
    if (ptr) {
        RingBuffer *buf = ptr;

        pthread_mutex_init(&buf->lock, 0);
        pthread_cond_init(&buf->cond, 0);
        buf->size = size;
        buf->elems = buf + 1;
        buf->elem_size = elem_size;
        ringbuffer_clear(buf);

        buf->dump = no_dump;
        buf->dump_ud = NULL;
        *rb = buf;
        return 0;
    }
    return -1;
}
Пример #3
0
int main(int argc, char **argv) {
    // For connect/authenticate failures
    int reconnect_delay = 1;

    // RingBuffer buffer for the writer
    char *writer_buffer = 0;

    LINFO("%s starting", APP_NAME);

    config_init(argc > 1 ? argv[1] : 0);
    pthread_create(&config.timer_thread.thread, 0, timer_thread_entry, (void *)&config.timer_thread);
    if (!config_read()) {
        return 1;
    }

    load_data();

    sighelper_sigaction(SIGHUP, reload_config);
    sighelper_sigaction(SIGUSR1, save_data);
    sighelper_sigaction(SIGTERM, terminate);
    sighelper_sigaction(SIGQUIT, terminate);
    sighelper_sigaction(SIGINT, terminate);

    LDEBUG("allocating writer buffer, size %d", config.writer.buffer);
    writer_buffer = malloc(config.writer.buffer);
    ringbuffer_init(&config.writer_thread.ringbuffer,
                    writer_buffer, config.writer.buffer);

    LDEBUG("creating reader queue, size %d", config.reader.queue);
    queue_init(&config.reader_thread.queue, config.reader.queue);

    while (running) {
        LINFO("connecting to %s:%d", config.network.host, config.network.port);

        if (net_connect(&config.socket, config.network.host, config.network.port)) {
            LINFO("opening XMPP stream to %s", config.component.hostname);
            if (!net_stream(&config.socket,
                            "xmcomp",
                            config.component.hostname,
                            config.component.password)) {
                net_disconnect(&config.socket);
            }
        }

        if (!config.socket.connected) {
            LERROR("retrying in %d second(s)", reconnect_delay);
            sleep(reconnect_delay);
            if (reconnect_delay < 60) {
                reconnect_delay <<= 1;
            }
            continue;
        }
        reconnect_delay = 1;

        LINFO("creating writer thread");
        config.writer_thread.socket = &config.socket;
        config.writer_thread.enabled = TRUE;
        pthread_create(&config.writer_thread.thread, 0, writer_thread_entry, (void *)&config.writer_thread);

        LINFO("creating reader thread");
        config.reader_thread.socket = &config.socket;
        config.reader_thread.enabled = TRUE;
        pthread_create(&config.reader_thread.thread, 0, reader_thread_entry, (void *)&config.reader_thread);

        LINFO("creating worker threads");
        config_apply();

        LINFO("started");
        LDEBUG("joining reader thread");
        pthread_join(config.reader_thread.thread, 0);
        // Switch ringbuffer to offline, indicating no more data is expected.
        // As soon as the writer finishes the job, it will terminate
        ringbuffer_offline(&config.writer_thread.ringbuffer);
        LDEBUG("joining writer thread");
        pthread_join(config.writer_thread.thread, 0);

        LINFO("clearing output buffer and disconnecting");
        ringbuffer_clear(&config.writer_thread.ringbuffer);

        net_unstream(&config.socket);
        net_disconnect(&config.socket);
    }

    LINFO("cleaning up");
    ringbuffer_destroy(&config.writer_thread.ringbuffer);
    queue_destroy(&config.reader_thread.queue);
    free(writer_buffer);
    config_destroy();

    return 0;
}
Пример #4
0
void ioreset()
{
    ringbuffer_clear(&ringbuffer);
}
Пример #5
0
static int socks5_src_do_connect(struct sserver_handle *handle, struct ssession *session) {
    
    // 1. parse
    // 2. clear buf;
    // 3. connect to dest addr
    // 4. set session.dstfd
    // 5. add response to sendbuf;
    // 6. add fd to writefds
    // 7. set session state to SSESSION_STATE_TRANSMIT
    
    /*
     rep:
     0x00        成功
     0x01        一般性失败
     0x02        规则不允许转发
     0x03        网络不可达
     0x04        主机不可达
     0x05        连接拒绝
     0x06        TTL超时
     0x07        不支持请求包中的CMD
     0x08        不支持请求包中的ATYP
     0x09-0xFF   unassigned
     */
    
    int ret = 0;
    char ver = 0x00;
    char cmd = 0x00;
    char rsv = 0x00;
    char atyp = 0x00;
    char ndstaddr = 0x00;
    uint32_t ip = 0x00;
    char dstaddr[256] = {0x00};
    uint16_t dstport = 0;
    
    char rep = 0x00;
    char nbndaddr = 0x00;
    char bndaddr[256] = {0x00};
    uint16_t bndport = 0;
    int nread = 0;
    
    struct ringbuffer_tran tran;
    struct ringbuffer *tranrb = NULL;
    
    tranrb = ringbuffer_transaction_begin(session->dstbuf, &tran);
    
    nread = ringbuffer_transaction_read(tranrb, &ver, 1);
    if(nread <= 0) {
        ringbuffer_transaction_rollback(session->dstbuf, &tran);
        return SE_NEEDMORE;
    }
    
    nread = ringbuffer_transaction_read(tranrb, &cmd, 1);
    if(nread <= 0) {
        ringbuffer_transaction_rollback(session->dstbuf, &tran);
        return SE_NEEDMORE;
    }
    
    nread = ringbuffer_transaction_read(tranrb, &rsv, 1);
    if(nread <= 0) {
        ringbuffer_transaction_rollback(session->dstbuf, &tran);
        return SE_NEEDMORE;
    }
    
    nread = ringbuffer_transaction_read(tranrb, &atyp, 1);
    if(nread <= 0) {
        ringbuffer_transaction_rollback(session->dstbuf, &tran);
        return SE_NEEDMORE;
    }
    
    switch (cmd) {
        case 0x01:
            break;
        case 0x02:
        case 0x03:
        default:
            rep = 0x07;
            goto pre_send;
            break;
    }
    
    switch(atyp) {
        case 0x01:	// ipv4
            nread = ringbuffer_transaction_read(tranrb, &ip, 4);
            if(nread <= 0) {
                ringbuffer_transaction_rollback(session->dstbuf, &tran);
                return SE_NEEDMORE;
            }
            nread = ringbuffer_transaction_read(tranrb, &dstport, 2);
            if(nread <= 0) {
                ringbuffer_transaction_rollback(session->dstbuf, &tran);
                return SE_NEEDMORE;
            }
            session->dstfd = tcp_socket_connect_with_ip(ip, dstport);
            break;
        case 0x03:	// domain
            nread = ringbuffer_transaction_read(tranrb, &ndstaddr, 1);
            if(nread <= 0) {
                ringbuffer_transaction_rollback(session->dstbuf, &tran);
                return SE_NEEDMORE;
            }
            
            nread = ringbuffer_transaction_read(tranrb, dstaddr, ndstaddr);
            if(nread <= 0) {
                ringbuffer_transaction_rollback(session->dstbuf, &tran);
                return SE_NEEDMORE;
            }
            
            nread = ringbuffer_transaction_read(tranrb, &dstport, 2);
            if(nread <= 0) {
                ringbuffer_transaction_rollback(session->dstbuf, &tran);
                return SE_NEEDMORE;
            }
            session->dstfd = tcp_socket_connect_with_domain(dstaddr, dstport);
            break;
        case 0x04:	// ipv6
            rep = 0x08;
            goto pre_send;
            break;
    }
    
    if(session->dstfd < 0) {
        switch (errno) {
            case ENETUNREACH:
                rep = 0x03;
                break;
            case EHOSTUNREACH:
                rep = 0x04;
                break;
            case ECONNREFUSED:
                rep = 0x05;
                break;
            default:
                rep = 0x01;
                break;
        }
    } else {
        FD_SET(session->dstfd, &handle->server->readfds);
        if(handle->server->maxfd < session->dstfd)
            handle->server->maxfd = session->dstfd;
    }

pre_send:
    atyp = 0x01;
    nbndaddr = 4;
    bndaddr[0] = '\0';
    bndaddr[1] = '\0';
    bndaddr[2] = '\0';
    bndaddr[3] = '\0';
    
    ringbuffer_clear(session->dstbuf);
    ringbuffer_write(session->srcbuf, &ver, 1);
    ringbuffer_write(session->srcbuf, &rep, 1);
    ringbuffer_write(session->srcbuf, &rsv, 1);
    ringbuffer_write(session->srcbuf, &atyp, 1);
    ringbuffer_write(session->srcbuf, &nbndaddr, 1);
    ringbuffer_write(session->srcbuf, bndaddr, nbndaddr);
    ringbuffer_write(session->srcbuf, &bndport, 2);
    
    FD_SET(session->srcfd, &handle->server->writefds);
    if(handle->server->maxfd < session->srcfd)
        handle->server->maxfd = session->srcfd;
    
    session->state = SSESSION_STATE_TRANSMIT;
    return ret;
}
Пример #6
0
/// "destructor", free up a ringbuffer_t's resources after you're done
void ringbuffer_done(ringbuffer_t *rb) {
	ringbuffer_clear(rb);
	rb->capacity = 0;
	free(rb->entries);
	rb->entries = NULL;
}