NS_INTERNAL void ns_call(struct ns_connection *nc, int ev, void *ev_data) { unsigned long flags_before; ns_event_handler_t ev_handler; DBG(("%p flags=%lu ev=%d ev_data=%p rmbl=%d", nc, nc->flags, ev, ev_data, (int) nc->recv_mbuf.len)); #ifndef NS_DISABLE_FILESYSTEM /* LCOV_EXCL_START */ if (nc->mgr->hexdump_file != NULL && ev != NS_POLL && ev != NS_SEND /* handled separately */) { int len = (ev == NS_RECV ? *(int *) ev_data : 0); ns_hexdump_connection(nc, nc->mgr->hexdump_file, len, ev); } /* LCOV_EXCL_STOP */ #endif /* * If protocol handler is specified, call it. Otherwise, call user-specified * event handler. */ ev_handler = nc->proto_handler ? nc->proto_handler : nc->handler; if (ev_handler != NULL) { flags_before = nc->flags; ev_handler(nc, ev, ev_data); if (nc->flags != flags_before) { nc->flags = (flags_before & ~_NS_CALLBACK_MODIFIABLE_FLAGS_MASK) | (nc->flags & _NS_CALLBACK_MODIFIABLE_FLAGS_MASK); } } }
static void ns_call(struct ns_connection *nc, int ev, void *ev_data) { if (nc->mgr->hexdump_file != NULL && ev != NS_POLL) { int len = (ev == NS_RECV || ev == NS_SEND) ? * (int *) ev_data : 0; ns_hexdump_connection(nc, nc->mgr->hexdump_file, len, ev); } /* * If protocol handler is specified, call it. Otherwise, call user-specified * event handler. */ (nc->proto_handler ? nc->proto_handler : nc->handler)(nc, ev, ev_data); }
static void ns_write_to_socket(struct ns_connection *conn) { struct mbuf *io = &conn->send_mbuf; int n = 0; assert(io->len > 0); #ifdef NS_ENABLE_SSL if (conn->ssl != NULL) { if (conn->flags & NSF_SSL_HANDSHAKE_DONE) { n = SSL_write(conn->ssl, io->buf, io->len); if (n <= 0) { int ssl_err = ns_ssl_err(conn, n); if (ssl_err == SSL_ERROR_WANT_READ || ssl_err == SSL_ERROR_WANT_WRITE) { return; /* Call us again */ } else { conn->flags |= NSF_CLOSE_IMMEDIATELY; } } else { /* Successful SSL operation, clear off SSL wait flags */ conn->flags &= ~(NSF_WANT_READ | NSF_WANT_WRITE); } } else { ns_ssl_begin(conn); return; } } else #endif { n = (int) NS_SEND_FUNC(conn->sock, io->buf, io->len, 0); } DBG(("%p %d bytes -> %d", conn, n, conn->sock)); if (ns_is_error(n)) { conn->flags |= NSF_CLOSE_IMMEDIATELY; } else if (n > 0) { #ifndef NS_DISABLE_FILESYSTEM /* LCOV_EXCL_START */ if (conn->mgr->hexdump_file != NULL) { ns_hexdump_connection(conn, conn->mgr->hexdump_file, n, NS_SEND); } /* LCOV_EXCL_STOP */ #endif mbuf_remove(io, n); } ns_call(conn, NS_SEND, &n); }
static const char *test_hexdump_file(void) { const char *path = "test_hexdump"; const char *want = "0xbeef :0 -> :0 3\n" "0000 66 6f 6f " " foo\n\n"; char *data, *got; size_t size; struct ns_connection *nc = (struct ns_connection *) calloc(1, sizeof(*nc)); /* "In the GNU system, non-null pointers are printed as unsigned integers, * as if a `%#x' conversion were used. Null pointers print as `(nil)'. * (Pointers might print differently in other systems.)" * indeed it prints 0x0 on apple. */ nc->user_data = (void *)0xbeef; truncate(path, 0); iobuf_append(&nc->send_iobuf, "foo", 3); iobuf_append(&nc->recv_iobuf, "bar", 3); ns_hexdump_connection(nc, path, 3, NS_SEND); iobuf_free(&nc->send_iobuf); iobuf_free(&nc->recv_iobuf); free(nc); ASSERT((data = read_file(path, &size)) != NULL); unlink(path); got = data; while(got-data < (int)size && *got++ != ' '); size -= got-data; ASSERT(strncmp(got, want, size) == 0); free(data); return NULL; }