/* Print message to buffer. If buffer is large enough to hold the message, * return buffer. If buffer is to small, allocate large enough buffer on heap, * and return allocated buffer. */ int ns_avprintf(char **buf, size_t size, const char *fmt, va_list ap) { va_list ap_copy; int len; va_copy(ap_copy, ap); len = vsnprintf(*buf, size, fmt, ap_copy); va_end(ap_copy); if (len < 0) { /* eCos and Windows are not standard-compliant and return -1 when * the buffer is too small. Keep allocating larger buffers until we * succeed or out of memory. */ *buf = NULL; while (len < 0) { NS_FREE(*buf); size *= 2; if ((*buf = (char *) NS_MALLOC(size)) == NULL) break; va_copy(ap_copy, ap); len = vsnprintf(*buf, size, fmt, ap_copy); va_end(ap_copy); } } else if (len > (int) size) { /* Standard-compliant code path. Allocate a buffer that is large enough. */ if ((*buf = (char *) NS_MALLOC(len + 1)) == NULL) { len = -1; } else { va_copy(ap_copy, ap); len = vsnprintf(*buf, len + 1, fmt, ap_copy); va_end(ap_copy); } } return len; }
void ns_hexdump_connection(struct ns_connection *nc, const char *path, int num_bytes, int ev) { const struct mbuf *io = ev == NS_SEND ? &nc->send_mbuf : &nc->recv_mbuf; FILE *fp; char *buf, src[60], dst[60]; int buf_size = num_bytes * 5 + 100; if ((fp = fopen(path, "a")) != NULL) { ns_sock_to_str(nc->sock, src, sizeof(src), 3); ns_sock_to_str(nc->sock, dst, sizeof(dst), 7); fprintf(fp, "%lu %p %s %s %s %d\n", (unsigned long) time(NULL), nc->user_data, src, ev == NS_RECV ? "<-" : ev == NS_SEND ? "->" : ev == NS_ACCEPT ? "<A" : ev == NS_CONNECT ? "C>" : "XX", dst, num_bytes); if (num_bytes > 0 && (buf = (char *) NS_MALLOC(buf_size)) != NULL) { ns_hexdump(io->buf + (ev == NS_SEND ? 0 : io->len) - (ev == NS_SEND ? 0 : num_bytes), num_bytes, buf, buf_size); fprintf(fp, "%s", buf); NS_FREE(buf); } fclose(fp); } }
/* * Send `printf`-style formatted data to the connection. * * See `ns_send` for more details on send semantics. */ int ns_vprintf(struct ns_connection *nc, const char *fmt, va_list ap) { char mem[NS_VPRINTF_BUFFER_SIZE], *buf = mem; int len; if ((len = ns_avprintf(&buf, sizeof(mem), fmt, ap)) > 0) { ns_out(nc, buf, len); } if (buf != mem && buf != NULL) { NS_FREE(buf); } return len; }
static void ns_destroy_conn(struct ns_connection *conn) { closesocket(conn->sock); iobuf_free(&conn->recv_iobuf); iobuf_free(&conn->send_iobuf); #ifdef NS_ENABLE_SSL if (conn->ssl != NULL) { SSL_free(conn->ssl); } if (conn->ssl_ctx != NULL) { SSL_CTX_free(conn->ssl_ctx); } #endif NS_FREE(conn); }
static void ns_destroy_conn(struct ns_connection *conn) { if (conn->sock != INVALID_SOCKET) { closesocket(conn->sock); /* * avoid users accidentally double close a socket * because it can lead to difficult to debug situations. * It would happen only if reusing a destroyed ns_connection * but it's not always possible to run the code through an * address sanitizer. */ conn->sock = INVALID_SOCKET; } mbuf_free(&conn->recv_mbuf); mbuf_free(&conn->send_mbuf); #ifdef NS_ENABLE_SSL if (conn->ssl != NULL) { SSL_free(conn->ssl); } if (conn->ssl_ctx != NULL) { SSL_CTX_free(conn->ssl_ctx); } #endif NS_FREE(conn); }
void iobuf_free(struct iobuf *iobuf) { if (iobuf != NULL) { NS_FREE(iobuf->buf); iobuf_init(iobuf, 0); } }