static void ns_write_to_socket(struct ns_connection *conn) { struct iobuf *io = &conn->send_iobuf; int n = 0; #ifdef NS_ENABLE_SSL if (conn->ssl != NULL) { 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 #endif { n = (int) send(conn->sock, io->buf, io->len, 0); } DBG(("%p %lu -> %d bytes", conn, conn->flags, n)); ns_call(conn, NS_SEND, &n); if (ns_is_error(n)) { conn->flags |= NSF_CLOSE_IMMEDIATELY; } else if (n > 0) { iobuf_remove(io, n); } }
static void ns_read_from_socket(struct ns_connection *conn) { char buf[NS_READ_BUFFER_SIZE]; int n = 0; if (conn->flags & NSF_CONNECTING) { int ok = 1, ret; (void) ret; socklen_t len = sizeof(ok); ret = getsockopt(conn->sock, SOL_SOCKET, SO_ERROR, (char *) &ok, &len); #ifdef NS_ENABLE_SSL if (ret == 0 && ok == 0 && conn->ssl != NULL) { ns_ssl_begin(conn); } #endif DBG(("%p connect ok=%d", conn, ok)); if (ok != 0) { conn->flags |= NSF_CLOSE_IMMEDIATELY; } else { conn->flags &= ~NSF_CONNECTING; } ns_call(conn, NS_CONNECT, &ok); return; } #ifdef NS_ENABLE_SSL if (conn->ssl != NULL) { if (conn->flags & NSF_SSL_HANDSHAKE_DONE) { /* SSL library may have more bytes ready to read then we ask to read. * Therefore, read in a loop until we read everything. Without the loop, * we skip to the next select() cycle which can just timeout. */ while ((n = SSL_read(conn->ssl, buf, sizeof(buf))) > 0) { DBG(("%p %d bytes <- %d (SSL)", conn, n, conn->sock)); mbuf_append(&conn->recv_mbuf, buf, n); ns_call(conn, NS_RECV, &n); } ns_ssl_err(conn, n); } else { ns_ssl_begin(conn); return; } } else #endif { while ((n = (int) NS_RECV_FUNC( conn->sock, buf, recv_avail_size(conn, sizeof(buf)), 0)) > 0) { DBG(("%p %d bytes (PLAIN) <- %d", conn, n, conn->sock)); mbuf_append(&conn->recv_mbuf, buf, n); ns_call(conn, NS_RECV, &n); } } if (ns_is_error(n)) { conn->flags |= NSF_CLOSE_IMMEDIATELY; } }
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); }
/* * Schedules an async connect for a resolved address and proto. * Called from two places: `ns_connect_opt()` and from async resolver. * When called from the async resolver, it must trigger `NS_CONNECT` event * with a failure flag to indicate connection failure. */ NS_INTERNAL struct ns_connection *ns_finish_connect(struct ns_connection *nc, int proto, union socket_address *sa, struct ns_add_sock_opts o) { sock_t sock = INVALID_SOCKET; int rc; DBG(("%p %s://%s:%hu", nc, proto == SOCK_DGRAM ? "udp" : "tcp", inet_ntoa(nc->sa.sin.sin_addr), ntohs(nc->sa.sin.sin_port))); if ((sock = socket(AF_INET, proto, 0)) == INVALID_SOCKET) { int failure = errno; NS_SET_PTRPTR(o.error_string, "cannot create socket"); if (nc->flags & NSF_CONNECTING) { ns_call(nc, NS_CONNECT, &failure); } ns_destroy_conn(nc); return NULL; } ns_set_non_blocking_mode(sock); rc = (proto == SOCK_DGRAM) ? 0 : connect(sock, &sa->sa, sizeof(sa->sin)); if (rc != 0 && ns_is_error(rc)) { NS_SET_PTRPTR(o.error_string, "cannot connect to socket"); if (nc->flags & NSF_CONNECTING) { ns_call(nc, NS_CONNECT, &rc); } ns_destroy_conn(nc); close(sock); return NULL; } /* Fire NS_CONNECT on next poll. */ nc->flags |= NSF_CONNECTING; /* No ns_destroy_conn() call after this! */ ns_set_sock(nc, sock); return nc; }
NsError ns_model_read_swc ( NsModel *model, NsSwcHeader *swc_header, const nschar *file_name, nsulong flags, nslong *line_num ) { NsError error; ns_assert( NULL != model ); ns_assert( NULL != swc_header ); ns_assert( NULL != file_name ); ns_log_entry( NS_LOG_ENTRY_FUNCTION, NS_FUNCTION "( model=" NS_FMT_STRING_DOUBLE_QUOTED ", swc_header=" NS_FMT_POINTER ", file_name=" NS_FMT_STRING_DOUBLE_QUOTED ", flags=" NS_FMT_ULONG ", line_num=" NS_FMT_POINTER " )", ns_model_get_name( model ), swc_header, file_name, flags, line_num ); error = ( flags & NS_SWC_MULTIPLE_FILES ) ? _ns_swc_read_multi_file( model, swc_header, file_name, flags, line_num ) : _ns_swc_read_single_file( model, swc_header, file_name, flags, line_num ); if( ! ns_is_error( error ) ) ns_model_function_edges_from_vertices( model ); return error; }
/* * Connect to a remote host. * * If successful, `NS_CONNECT` event will be delivered * to the new connection. `addr` format is the same as for the `ns_bind()` call, * just an IP address becomes mandatory: `[PROTO://]HOST:PORT`. * * `PROTO` could be `tcp://` or `udp://`. If `HOST` is not an IP * address, Fossa will resolve it - beware that standard blocking resolver * will be used. It is a good practice to pre-resolve hosts beforehands and * use only IP addresses to avoid blockin an IO thread. * * See the `ns_connect_opts` structure for a description of the optional * parameters. * * Returns a new outbound connection, or `NULL` on error. */ struct ns_connection *ns_connect_opt(struct ns_mgr *mgr, const char *address, ns_event_handler_t callback, struct ns_connect_opts opts) { sock_t sock = INVALID_SOCKET; struct ns_connection *nc = NULL; union socket_address sa; int rc, proto; struct ns_add_sock_opts add_sock_opts; if (ns_parse_address(address, &sa, &proto) == 0) { errno = 0; ns_set_error_string(opts.error_string, "cannot parse address"); return NULL; } if ((sock = socket(AF_INET, proto, 0)) == INVALID_SOCKET) { ns_set_error_string(opts.error_string, "cannot create socket"); return NULL; } ns_set_non_blocking_mode(sock); rc = (proto == SOCK_DGRAM) ? 0 : connect(sock, &sa.sa, sizeof(sa.sin)); NS_COPY_COMMON_CONNECTION_OPTIONS(&add_sock_opts, &opts); if (rc != 0 && ns_is_error(rc)) { ns_set_error_string(opts.error_string, "cannot connect to socket"); closesocket(sock); return NULL; } else if ((nc = ns_add_sock_opt(mgr, sock, callback, add_sock_opts)) == NULL) { /* opts.error_string set by ns_add_sock_opt */ closesocket(sock); return NULL; } nc->sa = sa; /* Important, cause UDP conns will use sendto() */ nc->flags |= (proto == SOCK_DGRAM) ? NSF_UDP : NSF_CONNECTING; return nc; }
static void ns_read_from_socket(struct ns_connection *conn) { char buf[NS_READ_BUFFER_SIZE]; int n = 0; if (conn->flags & NSF_CONNECTING) { int ok = 1, ret; socklen_t len = sizeof(ok); ret = getsockopt(conn->sock, SOL_SOCKET, SO_ERROR, (char *) &ok, &len); #ifdef NS_ENABLE_SSL if (ret == 0 && ok == 0 && conn->ssl != NULL) { int res = SSL_connect(conn->ssl); int ssl_err = ns_ssl_err(conn, res); if (res == 1) { conn->flags |= NSF_SSL_HANDSHAKE_DONE; } else if (ssl_err == SSL_ERROR_WANT_READ || ssl_err == SSL_ERROR_WANT_WRITE) { return; /* Call us again */ } else { ok = 1; } } #endif conn->flags &= ~NSF_CONNECTING; DBG(("%p ok=%d", conn, ok)); if (ok != 0) { conn->flags |= NSF_CLOSE_IMMEDIATELY; } ns_call(conn, NS_CONNECT, &ok); return; } #ifdef NS_ENABLE_SSL if (conn->ssl != NULL) { if (conn->flags & NSF_SSL_HANDSHAKE_DONE) { /* SSL library may have more bytes ready to read then we ask to read. * Therefore, read in a loop until we read everything. Without the loop, * we skip to the next select() cycle which can just timeout. */ while ((n = SSL_read(conn->ssl, buf, sizeof(buf))) > 0) { DBG(("%p %lu <- %d bytes (SSL)", conn, conn->flags, n)); iobuf_append(&conn->recv_iobuf, buf, n); ns_call(conn, NS_RECV, &n); } ns_ssl_err(conn, n); } else { int res = SSL_accept(conn->ssl); int ssl_err = ns_ssl_err(conn, res); if (res == 1) { conn->flags |= NSF_SSL_HANDSHAKE_DONE; } else if (ssl_err == SSL_ERROR_WANT_READ || ssl_err == SSL_ERROR_WANT_WRITE) { return; /* Call us again */ } else { conn->flags |= NSF_CLOSE_IMMEDIATELY; } return; } } else #endif { while ((n = (int) recv(conn->sock, buf, sizeof(buf), 0)) > 0) { DBG(("%p %lu <- %d bytes (PLAIN)", conn, conn->flags, n)); iobuf_append(&conn->recv_iobuf, buf, n); ns_call(conn, NS_RECV, &n); } } if (ns_is_error(n)) { conn->flags |= NSF_CLOSE_IMMEDIATELY; } }