static int addr_peer(void) { ne_socket *sock = ne_sock_create(); ne_inet_addr *ia, *ia2; unsigned int port = 9999, realport; int ret; ia = ne_iaddr_make(ne_iaddr_ipv4, raw_127); ONN("ne_iaddr_make returned NULL", ia == NULL); CALL(new_spawn_server(1, serve_close, NULL, &realport)); ONN("could not connect", ne_sock_connect(sock, ia, realport)); ia2 = ne_sock_peer(sock, &port); ret = ne_iaddr_cmp(ia, ia2); ONV(ret != 0, ("comparison of peer with server address was %d", ret)); ONV(port != realport, ("got peer port %u, expected %u", port, realport)); ne_sock_close(sock); CALL(await_server()); ne_iaddr_free(ia); ne_iaddr_free(ia2); return OK; }
void ne_close_connection(ne_session *sess) { if (sess->connected) { struct hook *hk; NE_DEBUG(NE_DBG_SOCKET, "sess: Closing connection.\n"); if (sess->notify_cb) { sess->status.cd.hostname = sess->nexthop->hostname; sess->notify_cb(sess->notify_ud, ne_status_disconnected, &sess->status); } /* Run the close_conn hooks. */ for (hk = sess->close_conn_hooks; hk != NULL; hk = hk->next) { ne_close_conn_fn fn = (ne_close_conn_fn)hk->fn; fn(hk->userdata); } ne_sock_close(sess->socket); sess->socket = NULL; NE_DEBUG(NE_DBG_SOCKET, "sess: Connection closed.\n"); } else { NE_DEBUG(NE_DBG_SOCKET, "sess: Not closing closed connection.\n"); } sess->connected = 0; }
static int to_end(ne_socket *sock) { to_finish = time(NULL); reap_server(); /* hopefully it's hung. */ ONN("timeout ignored, or very slow machine", to_finish - to_start > 3); ONN("close failed", ne_sock_close(sock)); return OK; }
static int just_connect(void) { ne_socket *sock; CALL(begin(&sock, serve_close, NULL)); ne_sock_close(sock); return await_server(); }
static int expect100(void) { ne_socket *sock = ne_sock_create(); char req[BUFSIZ], buf[BUFSIZ]; ne_status status = {0}; const ne_inet_addr *ia; int success = 0; if (strcmp(ne_get_scheme(i_session), "https") == 0) { t_context("skipping for SSL server"); return SKIP; } for (ia = ne_addr_first(i_address); ia && !success; ia = ne_addr_next(i_address)) success = ne_sock_connect(sock, ia, i_port) == 0; ONN("could not connect to server", !success); sprintf(req, "PUT %sexpect100 HTTP/1.1" EOL "Host: %s" EOL "Content-Length: 100" EOL "Expect: 100-continue" EOL EOL, i_path, ne_get_server_hostport(i_session)); NE_DEBUG(NE_DBG_SOCKET, "Request:\n%s", req); ONS("sending request", ne_sock_fullwrite(sock, req, strlen(req))); switch (ne_sock_block(sock, 30)) { case NE_SOCK_TIMEOUT: ONN("timeout waiting for interim response", FAIL); break; case 0: /* no error. */ break; default: ONN("error reading from socket", FAIL); break; } ONS("reading status line", ne_sock_readline(sock, buf, BUFSIZ)); NE_DEBUG(NE_DBG_HTTP, "[status] %s", buf); ONN("parse status line", ne_parse_statusline(buf, &status)); if (status.code == 100) { char rbuf[100] = {0}; ONN("write request body", ne_sock_fullwrite(sock, rbuf, 100)); } ne_sock_close(sock); return OK; }
/* Test that just does a connect then a close (but gets the close via * ne_sock_peek). */ static int peek_close(void) { ne_socket *sock; CALL(begin(&sock, serve_close, NULL)); CALL(expect_peek_close(sock)); ONN("close failed", ne_sock_close(sock)); return await_server(); }
static int error(void) { ne_socket *sock = ne_sock_create(); ne_sock_set_error(sock, "%s:%s", "fish", "42"); ONCMP("fish:42", ne_sock_error(sock), "socket error", "set"); ne_sock_close(sock); return OK; }
/* close 'sock', performing lingering close to avoid premature RST. */ static int close_socket(ne_socket *sock) { #ifdef HAVE_SHUTDOWN char buf[20]; int fd = ne_sock_fd(sock); shutdown(fd, 0); while (ne_sock_read(sock, buf, sizeof buf) > 0); #endif return ne_sock_close(sock); }
void ne_close_connection(ne_session *sess) { if (sess->connected) { NE_DEBUG(NE_DBG_SOCKET, "Closing connection.\n"); ne_sock_close(sess->socket); sess->socket = NULL; NE_DEBUG(NE_DBG_SOCKET, "Connection closed.\n"); } else { NE_DEBUG(NE_DBG_SOCKET, "(Not closing closed connection!).\n"); } sess->connected = 0; }
static int ssl_session_id(void) { ne_socket *sock; unsigned char buf[128]; size_t len1; CALL(begin(&sock, serve_close, NULL)); #ifdef SOCKET_SSL len1 = 0; ONN("retrieve session id length", ne_sock_sessid(sock, NULL, &len1)); if (len1 == 0) { /* recent versions of OpenSSL seem to do this, not sure * why or whether it's bad. */ finish(sock, 1); t_context("zero-length session ID, cannot test further"); return SKIP; } if (len1 < sizeof buf) { buf[len1] = 'Z'; } { size_t len2; len2 = sizeof buf; ONN("could not retrieve session id", ne_sock_sessid(sock, buf, &len2)); ONN("buffer size changed!?", len1 != len2); } ONN("buffer written past expected end", len1 < sizeof buf && buf[len1] != 'Z'); /* Attempt retrieval into too-short buffer: */ len1 = 0; ONN("success for buffer overflow case", ne_sock_sessid(sock, buf, &len1) == 0); #else len1 = sizeof buf; ONN("retrieved session id for non-SSL socket!?", ne_sock_sessid(sock, buf, &len1) == 0); #endif ne_sock_close(sock); return await_server(); }
/* when an EOF is received without a clean shutdown (close_notify message). */ static int ssl_truncate(void) { ne_socket *sock; int ret; CALL(begin(&sock, serve_truncate, NULL)); ret = ne_sock_read(sock, buffer, 1); ONV(ret != NE_SOCK_TRUNC, ("socket got error %d not truncation: `%s'", ret, ne_sock_error(sock))); ne_sock_close(sock); CALL(await_server()); return OK; }
static int line_toolong(void) { ne_socket *sock; ssize_t ret; DECL(oneline, "AAAAAA\n"); CALL(begin(&sock, serve_sstring, &oneline)); ret = ne_sock_readline(sock, buffer, 5); ONV(ret != NE_SOCK_ERROR, ("readline should fail on long line: %" NE_FMT_SSIZE_T, ret)); reap_server(); ne_sock_close(sock); return OK; }
/* No obvious way to reliably test a connect() timeout. But * www.example.com seems to drop packets on ports other than 80 so * that actually works pretty well. Disabled by default. */ static int connect_timeout(void) { static const unsigned char example_dot_com[] = "\xC0\x00\x22\xA6"; ne_socket *sock = ne_sock_create(); ne_inet_addr *ia = ne_iaddr_make(ne_iaddr_ipv4, example_dot_com); ne_sock_connect_timeout(sock, 1); TO_OP(ne_sock_connect(sock, ia, 8080)); ne_iaddr_free(ia); ne_sock_close(sock); return OK; }
/* harder to simulate closure cases for an SSL connection, since it * may be doing multiple read()s or write()s per ne_sock_* call. */ static int ssl_closure(void) { ne_socket *sock; ssize_t ret; CALL(begin(&sock, serve_close, NULL)); CALL(full_write(sock, "a", 1)); CALL(await_server()); do { ret = ne_sock_fullwrite(sock, "a", 1); } while (ret == 0); ONV(ret != NE_SOCK_RESET && ret != NE_SOCK_CLOSED, ("write got %" NE_FMT_SSIZE_T " not reset or closure: %s", ret, ne_sock_error(sock))); ne_sock_close(sock); return OK; }
/* Create and connect *sock to address addr on given port. */ static int do_connect(ne_socket **sock, ne_sock_addr *addr, unsigned int port) { const ne_inet_addr *ia; *sock = ne_sock_create(); ONN("could not create socket", *sock == NULL); for (ia = ne_addr_first(addr); ia; ia = ne_addr_next(addr)) { if (ne_sock_connect(*sock, ia, port) == 0) return OK; } t_context("could not connect to server: %s", ne_sock_error(*sock)); ne_sock_close(*sock); return FAIL; }
/* Connect to an address crafted using ne_iaddr_make rather than from * the resolver. */ static int addr_connect(void) { ne_socket *sock = ne_sock_create(); ne_inet_addr *ia; ia = ne_iaddr_make(ne_iaddr_ipv4, raw_127); ONN("ne_iaddr_make returned NULL", ia == NULL); CALL(spawn_server(7777, serve_close, NULL)); ONN("could not connect", ne_sock_connect(sock, ia, 7777)); ne_sock_close(sock); CALL(await_server()); ne_iaddr_free(ia); return OK; }
static int read_reset(void) { ne_socket *sock; ssize_t ret; CALL(begin(&sock, serve_reset, NULL)); CALL(full_write(sock, "a", 1)); CALL(await_server()); ret = ne_sock_read(sock, buffer, 1); if (ret == NE_SOCK_CLOSED) { ne_sock_close(sock); return SKIP; } ONV(ret != NE_SOCK_RESET, ("read got %" NE_FMT_SSIZE_T " not reset: %s", ret, ne_sock_error(sock))); return good_close(sock); }
static int test_connect(void) { const ne_inet_addr *ia; ne_socket *sock = NULL; unsigned int port = proxy_hostname ? proxy_port : i_port; for (ia = ne_addr_first(i_address); ia && !sock; ia = ne_addr_next(i_address)) sock = ne_sock_connect(ia, port); if (sock == NULL) { t_context("connection refused by `%s' port %d", i_hostname, port); return FAILHARD; } ne_sock_close(sock); return OK; }
void upsdrv_cleanup(void) { free(subdriver->configure); free(subdriver->subscribe); free(subdriver->summary); free(subdriver->getobject); free(subdriver->setobject); if (sock) { ne_sock_close(sock); } if (session) { ne_session_destroy(session); } ne_uri_free(&uri); }
static int line_long_chunked(void) { ne_socket *sock; ssize_t ret; DECL_LONG(line, 'Z', OVERLEN); CALL(begin(&sock, serve_sstring_slowly, &line)); FULLREAD("ZZZZZZZZ"); /* fill the buffer */ ret = ne_sock_readline(sock, buffer, sizeof buffer); ONV(ret != NE_SOCK_ERROR, ("readline gave %" NE_FMT_SSIZE_T " not failure", ret)); reap_server(); ne_sock_close(sock); ne_free(line.data); return OK; }
static int write_reset(void) { ne_socket *sock; int ret; CALL(begin(&sock, serve_reset, NULL)); CALL(full_write(sock, "a", 1)); CALL(await_server()); ret = ne_sock_fullwrite(sock, "a", 1); if (ret == 0) { ne_sock_close(sock); return SKIP; } if (ret == NE_SOCK_CLOSED) { t_warning("got EOF, failed to elicit TCP RST"); } else { ONV(ret != NE_SOCK_RESET, ("write got %d not reset: %s", ret, ne_sock_error(sock))); } return good_close(sock); }
static int try_prebind(int addr, int port) { ne_socket *sock = ne_sock_create(); ne_inet_addr *ia; char buf[128], line[256]; unsigned int srvport; ia = ne_iaddr_make(ne_iaddr_ipv4, raw_127); ONN("ne_iaddr_make returned NULL", ia == NULL); CALL(new_spawn_server(1, serve_ppeer, NULL, &srvport)); ne_sock_prebind(sock, addr ? ia : NULL, port ? 7778 : 0); ONN("could not connect", ne_sock_connect(sock, ia, srvport)); ne_snprintf(line, sizeof line, "%s@%d\n", ne_iaddr_print(ia, buf, sizeof buf), 7778); if (!port) { /* Don't know what port will be chosen, so... */ ssize_t ret = ne_sock_readline(sock, buffer, BUFSIZ); ONV(ret < 0, ("socket error `%s'", ne_sock_error(sock))); ONV(strncmp(line, buffer, strchr(line, '@') - line) != 0, ("bad address: '%s', expecting '%s'", buffer, line)); } else { LINE(line); } ne_sock_close(sock); CALL(await_server()); ne_iaddr_free(ia); return OK; }
static int good_close(ne_socket *sock) { NE_DEBUG(NE_DBG_SOCKET, "Socket error was %s\n", ne_sock_error(sock)); ONN("close failed", ne_sock_close(sock)); return OK; }
void upsdrv_updateinfo(void) { int ret, errors = 0; /* We really should be dealing with alarms through a separate callback, so that we can keep the * processing of alarms and polling for data separated. Currently, this isn't supported by the * driver main body, so we'll have to revert to polling each time we're called, unless the * socket indicates we're no longer connected. */ if (testvar("subscribe")) { char buf[LARGEBUF]; ret = ne_sock_read(sock, buf, sizeof(buf)); if (ret > 0) { /* alarm message received */ ne_xml_parser *parser = ne_xml_create(); upsdebugx(2, "%s: ne_sock_read(%d bytes) => %s", __func__, ret, buf); ne_xml_push_handler(parser, subdriver->startelm_cb, subdriver->cdata_cb, subdriver->endelm_cb, NULL); ne_xml_parse(parser, buf, strlen(buf)); ne_xml_destroy(parser); time(&lastheard); } else if ((ret == NE_SOCK_TIMEOUT) && (difftime(time(NULL), lastheard) < 180)) { /* timed out */ upsdebugx(2, "%s: ne_sock_read(timeout)", __func__); } else { /* connection closed or unknown error */ upslogx(LOG_ERR, "NSM connection with '%s' lost", uri.host); upsdebugx(2, "%s: ne_sock_read(%d) => %s", __func__, ret, ne_sock_error(sock)); ne_sock_close(sock); if (netxml_alarm_subscribe(subdriver->subscribe) == NE_OK) { extrafd = ne_sock_fd(sock); time(&lastheard); return; } dstate_datastale(); extrafd = -1; return; } } /* get additional data */ ret = netxml_get_page(subdriver->getobject); if (ret != NE_OK) { errors++; } ret = netxml_get_page(subdriver->summary); if (ret != NE_OK) { errors++; } if (errors > 1) { dstate_datastale(); return; } status_init(); alarm_init(); netxml_alarm_set(); alarm_commit(); netxml_status_set(); status_commit(); dstate_dataok(); }