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; }
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; }
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; }
void ioreset() { ringbuffer_clear(&ringbuffer); }
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; }
/// "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; }