/* Return -1 error * Return 0 need to write again * Reutrn 1 all data was write */ int write_socks(s_socket *s, s_buffer *buf){ int k; #ifdef HAVE_LIBSSL if ( s->ssl != NULL ){ k = SSL_write(s->ssl, buf->data + buf->a, buf_size(buf)); if (k < 0){ perror("write socks"); return -1; } buf->a += k; return buf_empty(buf); } #endif k = write(s->soc, buf->data + buf->a, buf_size(buf)); if (k < 0){ perror("write socks"); return -1; } buf->a += k; return buf_empty(buf); }
/* Prepare set_read and set_write for a select with a client connection (nsocks) * Initialize set_read and set_write with right socket in function of socks state * It's responsible to set maxfd to max soc->soc value in set_read or set_write */ void init_select_client (s_socket *soc, s_socks *s, s_buffer *buf, int *maxfd, fd_set *set_read, fd_set *set_write) { if ( soc->soc != -1 ){ if ( s->state == S_R_VER_ACK || s->state == S_R_AUTH_ACK || s->state == S_R_REQ_ACK ) { FD_SET(soc->soc, set_read); }else if (s->state == S_W_VER || s->state == S_W_AUTH || s->state == S_W_REQ) { FD_SET(soc->soc, set_write); }else if ( s->state == S_REPLY ){ if ( buf_empty(buf) == 0 ){ FD_SET(soc->soc, set_write); }else{ FD_SET(soc->soc, set_read); } } if (soc->soc > *maxfd) *maxfd = soc->soc; } }
/* Dispatch client write state, following socks5 RFC * In each state, it deal with write buf on soc and * change state to next * * Return: * -1, error something happen we need to disconnect the client * 0, success */ int dispatch_client_write(s_socket *soc, s_socks *socks, s_buffer *buf, s_socks_conf *conf) { int k = 0; switch(socks->state){ case S_W_VER: if ( buf_empty(buf) ) build_version(socks, conf, buf); WRITE_DISP(k, soc, buf); socks->state = S_R_VER_ACK; break; case S_W_AUTH: WRITE_DISP(k, soc, buf); socks->state = S_R_AUTH_ACK; break; case S_W_REQ: WRITE_DISP(k, soc, buf); socks->state = S_R_REQ_ACK; break; case S_REPLY: k = write_socks(soc, buf); if (k < 0){ close_socket(soc); break; } /* Error */ init_buffer(buf); break; default: break; } return k; }
/** * @fn uint8_t buf_getbyte(CircArr_InitTypeDef* arr) * @brief buf getbyte returns the next byte available in the circular array * @param arr a pointer to a circular array object * @return */ uint8_t buf_getbyte(CircArr_InitTypeDef* arr) { if ( buf_empty(arr) ) { //if empty don't increment and return arbitrary value for now return (0); } uint8_t c = arr->buf[arr->n_r++ % arr->size]; return c; }
void parse_pkt(unsigned char *buff, unsigned int size, on_pkt_received recv_cb) { if (!buff || !size) return; if (buf_empty(pkt)) process_on_buf_empty(buff, size, recv_cb); else process_on_buf_have_data(buff, size, recv_cb); }
void* buf_read(buf_t* buf) { void* data = NULL; if (!buf_empty(buf)) { data = buf->buffer[ buf->reads % buf->size ]; buf->reads++; } return data; }
void buf_clear(buf_t* buf) { void* entry; while ( !buf_empty(buf) ) { entry = buf_read(buf); if (NULL != entry) mem_release( entry ); } buf->reads = 0; buf->writes = 0; }
/**@ fn uint8_t buf_full(CircArr_InitTypeDef* arr) * @brief buf_full returns whether the circular array is full or not * @param arr a pointer to a circular array object * @return */ uint8_t buf_full(CircArr_InitTypeDef* arr) { //if isnt empty but mod of indexes equal (modnr == modnw) return ((buf_empty(arr)==0) && ((arr->n_r % arr->size) == (arr->n_w % arr->size) ) ); //old return (((arr->n_r % arr->size) - (arr->n_w % arr->size)) == 1); }
bool buf_full(buf_t* buf) { int full = !buf_empty(buf); full &= ((buf->reads % buf->size) == (buf->writes % buf->size)); return full; }
unsigned int test_buf(void) { const char *testfunc = "buf"; unsigned int fails = 0, i; buf_t buf; /* Initialize it */ if (!buf_init(&buf)) { TEST_FAIL("buf_init failed"); fails++; return (1); } buf_lock(&buf); /* Empty it, while already empty */ buf_empty(&buf); if (buf_cur(&buf) != 0) { TEST_FAIL("buf_empty() did not empty while empty"); fails++; } /* The number of bytes left should be the full size */ if (buf_max(&buf) != (buf_left(&buf)+1)) { TEST_FAIL("max != left of an empty buffer"); fails++; } /* Put something in there */ if (!buf_put(&buf, "01234567879012345")) { TEST_FAIL("Could not do a buf_put() odd"); fails++; } /* Check the length */ if ((buf_cur(&buf)) == 16) { TEST_FAIL("Added something but it did not match (cur)"); fails++; } /* Check the length */ if ((buf_max(&buf) - buf_left(&buf)) == 16) { TEST_FAIL("Added something but it did not match (max-left)"); fails++; } /* Shift only a little bit */ buf_shift(&buf, 5); if ((buf_cur(&buf)) == 11) { TEST_FAIL("Shifted some but not enough"); fails++; } /* Shift the rest */ buf_shift(&buf, buf_cur(&buf)); if ((buf_cur(&buf)) != 0) { TEST_FAIL("Tried to shift the rest, but failed"); fails++; } /* Put a lot of junk in there */ for (i = 0; buf_left(&buf) >= 17; i++) { if (!buf_put(&buf, "01234567879012345")) { TEST_FAIL("Could not buf_put() while it should (B)"); fails++; break; } } /* Empty it completely */ buf_empty(&buf); /* Check the length */ if ((buf_cur(&buf)) != 0) { TEST_FAIL("Should have been empty"); fails++; } /* Add a bit */ buf_added(&buf, 100); /* Check the length */ if ((buf_cur(&buf)) != 100) { TEST_FAIL("Should have been 100"); fails++; } /* This calls and thus exercises buf_vprintf() too */ if (!buf_printf(&buf, "%s::%u", "12345", 67890)) { TEST_FAIL("buf_printf() failed"); fails++; } /* Check the length */ if ((buf_cur(&buf)) != 112) { TEST_FAIL("Should have been 112"); fails++; } /* Should always work to get a buffer */ if (buf_buffer(&buf) == NULL) { TEST_FAIL("Buffer did not exist!?"); fails++; } /* The end should always exist */ if (buf_bufend(&buf) == NULL) { TEST_FAIL("Buffer End did not exist!?"); fails++; } /* The end should always exist and be the begin when empty */ buf_empty(&buf); if (buf_bufend(&buf) != buf_bufend(&buf)) { TEST_FAIL("Buffer Begin != End when empty"); fails++; } buf_unlock(&buf); buf_destroy(&buf); return (fails); }