Beispiel #1
0
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;
}
Beispiel #2
0
/* This runs as the child process. */
static int server_child(int readyfd, struct in_addr addr, int port,
			server_fn callback, void *userdata)
{
    ne_socket *s = ne_sock_create();
    int ret, listener;

    in_child();

    listener = do_listen(addr, port);
    if (listener < 0)
	return FAIL;

#ifdef USE_PIPE
    /* Tell the parent we're ready for the request. */
    if (write(readyfd, "a", 1) != 1) abort();
#endif

    ONN("accept failed", ne_sock_accept(s, listener));

    ret = callback(s, userdata);

    close_socket(s);

    return ret;
}
Beispiel #3
0
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;
}
Beispiel #4
0
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;
}
Beispiel #5
0
/* 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;
}
Beispiel #6
0
/* 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;
}
Beispiel #7
0
/* 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;
}
Beispiel #8
0
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;
}
Beispiel #9
0
int spawn_server_repeat(int port, server_fn fn, void *userdata, int n)
{
    int fds[2];

#ifdef USE_PIPE
    if (pipe(fds)) {
	perror("spawn_server: pipe");
	return FAIL;
    }
#else
    /* avoid using uninitialized variable. */
    fds[0] = fds[1] = 0;
#endif

    child = fork();

    if (child == 0) {
	/* this is the child. */
	int listener, count = 0;

	in_child();

	listener = do_listen(lh_addr, port);

#ifdef USE_PIPE
	if (write(fds[1], "Z", 1) != 1) abort();
#endif

	close(fds[1]);
	close(fds[0]);

	/* Loop serving requests. */
	while (++count < n) {
	    ne_socket *sock = ne_sock_create();
	    int ret;

	    NE_DEBUG(NE_DBG_HTTP, "child awaiting connection #%d.\n", count);
	    ONN("accept failed", ne_sock_accept(sock, listener));
	    ret = fn(sock, userdata);
	    close_socket(sock);
	    NE_DEBUG(NE_DBG_HTTP, "child served request, %d.\n", ret);
	    if (ret) {
		printf("server child failed: %s\n", test_context);
		exit(-1);
	    }
	    /* don't send back notification to parent more than
	     * once. */
	}

	NE_DEBUG(NE_DBG_HTTP, "child aborted.\n");
	close(listener);

	exit(-1);

    } else {
	char ch;
	/* this is the parent. wait for the child to get ready */
#ifdef USE_PIPE
	if (read(fds[0], &ch, 1) < 0)
	    perror("parent read");

	close(fds[0]);
	close(fds[1]);
#else
	minisleep();
#endif
    }

    return OK;
}
Beispiel #10
0
static int netxml_alarm_subscribe(const char *page)
{
	int	ret, port = -1, secret = -1;
	char	buf[LARGEBUF], *s;
	ne_request	*request;
	ne_sock_addr	*addr;
	const ne_inet_addr	*ai;
	char	resp_buf[LARGEBUF];

	/* Clear response buffer */
	memset(resp_buf, 0, sizeof(resp_buf));

	upsdebugx(2, "%s: %s", __func__, page);

	sock = ne_sock_create();

	if (gethostname(buf, sizeof(buf)) == 0) {
		dstate_setinfo("driver.hostname", "%s", buf);
	} else {
		dstate_setinfo("driver.hostname", "<unknown>");
	}

#ifdef HAVE_NE_SOCK_CONNECT_TIMEOUT
	ne_sock_connect_timeout(sock, timeout);
#endif
	ne_sock_read_timeout(sock, 1);

	netxml_get_page(subdriver->configure);

	snprintf(buf, sizeof(buf),	"<?xml version=\"1.0\"?>\n");
	snprintfcat(buf, sizeof(buf),	"<Subscribe>\n");
	snprintfcat(buf, sizeof(buf),		"<Class>%s v%s</Class>\n", progname, DRIVER_VERSION);
	snprintfcat(buf, sizeof(buf),		"<Type>connected socket</Type>\n");
	snprintfcat(buf, sizeof(buf),		"<HostName>%s</HostName>\n", dstate_getinfo("driver.hostname"));
	snprintfcat(buf, sizeof(buf),		"<XMLClientParameters>\n");
	snprintfcat(buf, sizeof(buf),		"<ShutdownDuration>%d</ShutdownDuration>\n", shutdown_duration);
	if( shutdown_timer > 0 ) {
		snprintfcat(buf, sizeof(buf),	"<ShutdownTimer>%d</ShutdownTimer>\r\n", shutdown_timer);
	}
	else {
		snprintfcat(buf, sizeof(buf),	"<ShutdownTimer>NONE</ShutdownTimer>\n");
	}
	snprintfcat(buf, sizeof(buf),			"<AutoConfig>LOCAL</AutoConfig>\n");
	snprintfcat(buf, sizeof(buf),			"<OutletGroup>1</OutletGroup>\n");
	snprintfcat(buf, sizeof(buf),		"</XMLClientParameters>\n");
	snprintfcat(buf, sizeof(buf),		"<Warning></Warning>\n");
	snprintfcat(buf, sizeof(buf),	"</Subscribe>\n");

	/* now send subscription message setting all the proper flags */
	request = ne_request_create(session, "POST", page);
	ne_set_request_body_buffer(request, buf, strlen(buf));

	/* as the NMC reply is not xml standard compliant let's parse it this way */
	do {
#ifndef HAVE_NE_SOCK_CONNECT_TIMEOUT
		alarm(timeout+1);
#endif
		ret = ne_begin_request(request);

#ifndef HAVE_NE_SOCK_CONNECT_TIMEOUT
		alarm(0);
#endif
		if (ret != NE_OK) {
			break;
		}

		ret = ne_read_response_block(request, resp_buf, sizeof(resp_buf));

		if (ret == NE_OK) {
			ret = ne_end_request(request);
		}

	} while (ret == NE_RETRY);

	ne_request_destroy(request);

	/* due to different formats used by the various NMCs, we need to\
	   break up the reply in lines and parse each one separately */
	for (s = strtok(resp_buf, "\r\n"); s != NULL; s = strtok(NULL, "\r\n")) {
		upsdebugx(2, "%s: parsing %s", __func__, s);

		if (!strncasecmp(s, "<Port>", 6) && (sscanf(s+6, "%u", &port) != 1)) {
			return NE_RETRY;
		}

		if (!strncasecmp(s, "<Secret>", 8) && (sscanf(s+8, "%u", &secret) != 1)) {
			return NE_RETRY;
		}
	}

	if ((port == -1) || (secret == -1)) {
		upsdebugx(2, "%s: parsing initial subcription failed", __func__);
		return NE_RETRY;
	}

	/* Resolve the given hostname.  'flags' must be zero.  Hex
	* string IPv6 addresses (e.g. `::1') may be enclosed in brackets
	* (e.g. `[::1]'). */
	addr = ne_addr_resolve(uri.host, 0);

	/* Returns zero if name resolution was successful, non-zero on
	* error. */
	if (ne_addr_result(addr) != 0) {
		upsdebugx(2, "%s: name resolution failure on %s: %s", __func__, uri.host, ne_addr_error(addr, buf, sizeof(buf)));
		ne_addr_destroy(addr);
		return NE_RETRY;
	}

	for (ai = ne_addr_first(addr); ai != NULL; ai = ne_addr_next(addr)) {

		upsdebugx(2, "%s: connecting to host %s port %d", __func__, ne_iaddr_print(ai, buf, sizeof(buf)), port);

#ifndef HAVE_NE_SOCK_CONNECT_TIMEOUT
		alarm(timeout+1);
#endif
		ret = ne_sock_connect(sock, ai, port);

#ifndef HAVE_NE_SOCK_CONNECT_TIMEOUT
		alarm(0);
#endif
		if (ret == NE_OK) {
			upsdebugx(2, "%s: connection to %s open on fd %d", __func__, uri.host, ne_sock_fd(sock));
			break;
		}
	}

	ne_addr_destroy(addr);

	if (ai == NULL) {
		upsdebugx(2, "%s: failed to create listening socket", __func__);
		return NE_RETRY;
	}

	snprintf(buf, sizeof(buf), "<Subscription Identification=\"%u\"></Subscription>", secret);
	ret = ne_sock_fullwrite(sock, buf, strlen(buf) + 1);

	if (ret != NE_OK) {
		upsdebugx(2, "%s: send failed: %s", __func__, ne_sock_error(sock));
		return NE_RETRY;
	}

	ret = ne_sock_read(sock, buf, sizeof(buf));

	if (ret < 1) {
		upsdebugx(2, "%s: read failed: %s", __func__, ne_sock_error(sock));
		return NE_RETRY;
	}

	if (strcasecmp(buf, "<Subscription Answer=\"ok\"></Subscription>")) {
		upsdebugx(2, "%s: subscription rejected", __func__);
		return NE_RETRY;
	}

	upslogx(LOG_INFO, "NSM connection to '%s' established", uri.host);
	return NE_OK;
}