Пример #1
0
Файл: proxy.c Проект: fbbs/fbbs
static void connection_error_callback(int fd)
{
	connection_t *conn = connections + fd;
	bool client = conn->client;
	int remote_fd = valid_remote_fd(fd) ? conn->remote_fd : REMOTE_NULL;

	connection_reset(conn);
	ev_io_stop(EV_DEFAULT_ &conn->watcher);
	close(fd);

	if (client) {
		if (remote_fd >= 0) {
			server_t *server = find_server(remote_fd);
			if (server && server->pid >= 0)
				kill(server->pid, SIGHUP);
		}
	} else {
		server_t *server = find_server(fd);
		if (server) {
			server->pid = -1;
			server->fd = -1;
			--server_size;
			if (proxy_shutdown) {
				if (!server_size)
					ev_break(EV_DEFAULT_ EVBREAK_ALL);
			} else {
				spawn_server(server);
			}
		}
	}
}
Пример #2
0
static int addr_peer(void)
{
    ne_socket *sock = ne_sock_create();
    ne_inet_addr *ia, *ia2;
    unsigned int port = 9999;
    int ret;

    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));

    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 != 7777, ("got peer port %u", port));

    ne_sock_close(sock);
    CALL(await_server());

    ne_iaddr_free(ia);
    ne_iaddr_free(ia2);
    return OK;
}
Пример #3
0
int scan_connected_devices(detector_state_t *state) {
	struct udev_list_entry *cursor;
	struct udev_enumerate *ue;
	struct udev_device *ud;

	const char *devnode = NULL;

	if( !(ue = udev_enumerate_new(state->u)) )
		return 1;

	udev_enumerate_add_match_subsystem(ue, "tty");
	udev_enumerate_add_match_property(ue, "ID_BUS", "usb");
	udev_enumerate_scan_devices(ue);
	cursor = udev_enumerate_get_list_entry(ue);

	do {
		ud = udev_device_new_from_syspath(
			state->u, udev_list_entry_get_name(cursor));

		if( (devnode = udev_device_get_devnode(ud)) )
			spawn_server(state->exec_path, devnode);

		udev_device_unref(ud);
	} while( (cursor = udev_list_entry_get_next(cursor)) );

	udev_enumerate_unref(ue);
	return 0;
}
Пример #4
0
static monome_t *monitor_attach(detector_state_t *state) {
	struct udev_device *ud;
	struct pollfd fds[1];

	fds[0].fd = udev_monitor_get_fd(state->um);
	fds[0].events = POLLIN;

	do {
		if( poll(fds, 1, -1) < 0 )
			switch( errno ) {
			case EINVAL:
				perror("error in poll()");
				exit(1);

			case EINTR:
			case EAGAIN:
				continue;
			}

		ud = udev_monitor_receive_device(state->um);

		/* check if this was an add event.
		   "add"[0] == 'a' */
		if( *(udev_device_get_action(ud)) == 'a' )
			spawn_server(state->exec_path, udev_device_get_devnode(ud));

		udev_device_unref(ud);
	} while( 1 );
}
Пример #5
0
static int begin_socks(ne_socket **sock, struct socks_server *srv,
                       server_fn server, void *userdata)
{
    srv->server = server;
    srv->userdata = userdata;
    srv->say_hello = 1;
    CALL(spawn_server(7777, socks_server, srv));
    return do_connect(sock, localhost, 7777);
}
Пример #6
0
static int begin(ne_socket **sock, server_fn fn, void *ud)
{
    struct serve_pair pair;
    pair.fn = fn;
    pair.userdata = ud;
    CALL(spawn_server(7777, wrap_serve, &pair));
    CALL(do_connect(sock, localhost, 7777));
    ONV(ne_sock_connect_ssl(*sock, client_ctx, NULL),
	("SSL negotation failed: %s", ne_sock_error(*sock)));
    return OK;
}
Пример #7
0
Файл: proxy.c Проект: fbbs/fbbs
int main(int argc, char **argv)
{
	const char *socket_path = getenv("FBBS_SOCKET_PATH");
	server_path = getenv("FBBS_SERVER_PATH");
	if (!socket_path || !server_path)
		return EXIT_FAILURE;

	start_daemon();

	const char *fbbs_max_servers = getenv("FBBS_MAX_SERVERS");
	if (fbbs_max_servers)
		max_servers = strtol(fbbs_max_servers, NULL, 10);
	if (max_servers <= 0)
		max_servers = DEFAULT_MAX_SERVERS;
	servers = malloc(sizeof(*servers) * max_servers);
	if (!servers)
		return EXIT_FAILURE;
	for (int i = 0; i < max_servers; ++i) {
		servers[i].pid = -1;
		servers[i].fd = -1;
	}

	int max_clients = 0;
	const char *fbbs_max_clients = getenv("FBBS_MAX_CLIENTS");
	if (fbbs_max_clients)
		max_clients = strtol(fbbs_max_clients, NULL, 10);
	max_clients = check_max_clients(max_clients);
	if (max_clients <= 0)
		return EXIT_FAILURE;

	if (setgid(BBSGID) != 0)
		return EXIT_FAILURE;
	if (setuid(BBSUID) != 0)
		return EXIT_FAILURE;

	int fd = bind_unix_path(socket_path);
	if (fd < 0)
		return EXIT_FAILURE;

	fb_signal(SIGPIPE, SIG_IGN);
	fb_signal(SIGCHLD, reap_child);
	fb_signal(SIGTERM, shutdown_backend);

	for (int i = 0; i < max_servers; ++i) {
		if (!spawn_server(servers + i)) {
			kill_servers();
			return EXIT_FAILURE;
		}
	}

	ev_run(EV_DEFAULT_ 0);
	return EXIT_SUCCESS;
}
int
main(int argc, char **argv)
{
    int sock, nserver0;
    int errfd;
    pthread_t th;

    pthread_create(&th, NULL, response_to_search, NULL);
    parseArgv(argc, argv);
    if (Daemonize) {
        if (fork()) {
            exit(0);
        }
        else {
            close(2);
            errfd = open(LogFileName, O_RDWR | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR);
            if (errfd < 0) {
                perror("open:");
            }
            close(0);
            close(1);
        }
    }

    initEnv();
    sock = create_daemon_socket(RC_DAEMON_IP_PORT, NBACKLOG);
    if (sock == -1) {
	WARN(0, "create_daemon_socket() failed\n");
	exit(1);
    }
    nserver0 = Nserver;
    while (1) {
        if (Nserver < RC_NSERVERMAX) {
            spawn_server(sock);

            if (nserver0 != Nserver) {
                if (Nserver < RC_NSERVERMAX) {
                    WARN(0, "%d servers active (%d max possible).\n", Nserver, RC_NSERVERMAX);
                }
                else {
                    WARN(0, "%d servers active. reached the limit.\n", Nserver);
                }
            }
        }
        sleep(1);
        nserver0 = Nserver;
    }
    WARN(0, "%s: cannot be reached.\n", __FILE__);

    pthread_join(th, NULL);
    exit(1);
}
Пример #9
0
/* ensure that ne_redirect_location returns NULL when no redirect has
 * been encountered, or redirect hooks aren't registered. */
static int no_redirect(void)
{
    ne_session *sess = ne_session_create("http", "localhost", 7777);
    const ne_uri *loc;

    ONN("redirect non-NULL before register", ne_redirect_location(sess));
    ne_redirect_register(sess);
    ONN("initial redirect non-NULL", ne_redirect_location(sess));

    CALL(spawn_server(7777, single_serve_string,
                      "HTTP/1.0 200 OK\r\n\r\n\r\n"));
    ONREQ(any_request(sess, "/noredir"));
    CALL(await_server());

    ONN("redirect non-NULL after non-redir req", ne_redirect_location(sess));

    CALL(spawn_server(7777, single_serve_string, "HTTP/1.0 302 Get Ye Away\r\n"
                      "Location: /blah\r\n" "\r\n"));
    CALL(process_redir(sess, "/foo", &loc));
    CALL(await_server());

    ne_session_destroy(sess);
    return OK;
}
Пример #10
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;
}
Пример #11
0
int main(int argc, char **argv)
{
	struct mrpc_conn_set *sset;
	struct mrpc_conn_set *cset;
	struct mrpc_connection *conn;
	char *port;
	int ret;
	int i;
	pthread_t thr;

	expect(sem_init(&accepted, 0, 0), 0);
	expect(sem_init(&ready, 0, 0), 0);
	expect(sem_init(&complete, 0, 0), 0);
	sset=spawn_server(&port, proto_server, do_accept, NULL, 1);
	mrpc_set_disconnect_func(sset, server_disconnect);

	if (mrpc_conn_set_create(&cset, proto_client, NULL))
		die("Couldn't allocate conn set");
	mrpc_set_disconnect_func(cset, disconnect_user);
	start_monitored_dispatcher(cset);

	ret=mrpc_conn_create(&conn, cset, NULL);
	if (ret)
		die("%s", strerror(ret));
	ret=mrpc_connect(conn, AF_UNSPEC, "localhost", port);
	if (ret)
		die("%s", strerror(ret));

	expect(proto_ping_async(conn, ping_cb, NULL), MINIRPC_OK);
	pthread_create(&thr, NULL, do_sync_ping, conn);
	expect(pthread_detach(thr), 0);
	sem_wait(&ready);
	expect(mrpc_conn_close(conn), 0);
	expect(proto_ping(conn), MINIRPC_NETWORK_FAILURE);
	expect(mrpc_conn_close(conn), EALREADY);
	for (i=0; i<2; i++)
		sem_wait(&complete);
	mrpc_conn_unref(conn);
	mrpc_conn_set_unref(cset);
	sem_wait(&accepted);
	mrpc_listen_close(sset);
	mrpc_conn_set_unref(sset);
	expect_disconnects(1, 1, 0);
	free(port);
	return 0;
}
Пример #12
0
int main(int argc, char **argv)
{
	struct mrpc_conn_set *sset;
	struct mrpc_conn_set *cset;
	struct mrpc_connection *conn;
	char *port;
	int ret;

	sem_init(&accepted, 0, 0);
	sset=spawn_server(&port, proto_server, do_accept, NULL, 1);
	mrpc_set_disconnect_func(sset, disconnect_normal_no_unref);
	mrpc_conn_set_ref(sset);

	if (mrpc_conn_set_create(&cset, proto_client, NULL))
		die("Couldn't allocate conn set");
	mrpc_conn_set_ref(cset);
	mrpc_set_disconnect_func(cset, disconnect_user);
	start_monitored_dispatcher(cset);

	ret=mrpc_conn_create(&conn, cset, NULL);
	if (ret)
		die("%s", strerror(ret));
	ret=mrpc_connect(conn, AF_UNSPEC, "localhost", port);
	if (ret)
		die("%s", strerror(ret));
	mrpc_conn_ref(conn);
	mrpc_conn_set_unref(cset);
	mrpc_conn_set_unref(cset);
	mrpc_conn_set_unref(sset);
	mrpc_conn_set_unref(sset);
	sem_wait(&accepted);
	mrpc_listen_close(sset);
	mrpc_conn_unref(conn);
	mrpc_conn_unref(conn);

	sync_client_set_ops(conn);
	sync_client_run(conn);
	trigger_callback_sync(conn);
	invalidate_sync(conn);
	mrpc_conn_close(conn);
	expect_disconnects(1, 1, 0);
	sem_destroy(&accepted);
	free(port);
	return 0;
}
Пример #13
0
int
main(int argc, char **argv)
{
    int sock, nserver0;
    int errfd;

    parseArgv(argc, argv);
    if (Daemonize) {
        if (fork()) {
            exit(0);
        }
        else {
            close(2);
            errfd = open(LogFileName, O_RDWR | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR);
            if (errfd < 0) {
                perror("open:");
            }
            close(0);
            close(1);
        }
    }

    initEnv();
    sock = create_daemon_socket(RC_DAEMON_IP_PORT, NSERVERMAX);
    if (sock == -1) {
	WARN(0, "create_daemon_socket() failed\n");
	exit(1);
    }
    nserver0 = Nserver;
    while (1) {
        if (Nserver < NSERVERMAX) {
            spawn_server(sock);
        }
        else {
            if (nserver0 != Nserver) {
                WARN(0, "already max possible clients (=%d) active.\n", Nserver);
            }
            sleep(1);
        }
        nserver0 = Nserver;
    }
    WARN(0, "%s: cannot be reached.\n", __FILE__);
    exit(1);
}
Пример #14
0
static int try_prebind(int addr, int port)
{
    ne_socket *sock = ne_sock_create();
    ne_inet_addr *ia;
    char buf[128], line[256];

    ia = ne_iaddr_make(ne_iaddr_ipv4, raw_127);
    ONN("ne_iaddr_make returned NULL", ia == NULL);

    CALL(spawn_server(7777, serve_ppeer, NULL));

    ne_sock_prebind(sock, addr ? ia : NULL, port ? 7778 : 0);

    ONN("could not connect", ne_sock_connect(sock, ia, 7777));

    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;
}
Пример #15
0
int main(int argc, char **argv)
{
	struct mrpc_conn_set *sset;
	struct mrpc_conn_set *cset;
	struct mrpc_connection *conn;
	char *port;
	int ret;
	int i;

	sset=spawn_server(&port, proto_server, do_accept, NULL, 1);
	mrpc_set_disconnect_func(sset, disconnect_normal);

	if (mrpc_conn_set_create(&cset, proto_client, NULL))
		die("Couldn't allocate conn set");
	mrpc_set_disconnect_func(cset, disconnect_user);
	start_monitored_dispatcher(cset);

	ret=mrpc_conn_create(&conn, cset, NULL);
	if (ret)
		die("%s", strerror(ret));
	ret=mrpc_connect(conn, AF_UNSPEC, "localhost", port);
	if (ret)
		die("%s", strerror(ret));

	for (i=0; i<ITERS; i++) {
		expect(proto_ping(conn), 0);
		expect(proto_ping(conn), 1);
	}

	mrpc_conn_close(conn);
	mrpc_conn_unref(conn);
	mrpc_conn_set_unref(cset);
	mrpc_listen_close(sset);
	mrpc_conn_set_unref(sset);
	expect_disconnects(1, 1, 0);
	free(port);
	return 0;
}
Пример #16
0
int main(int argc, char **argv)
{
	struct mrpc_conn_set *sset;
	struct mrpc_conn_set *cset;
	struct mrpc_connection *conn;
	struct sockaddr_in addr;
	socklen_t addrlen;
	char *set_port;
	char skt_port[8];
	int cfd;
	int lfd;
	int sfd;
	unsigned seq;
	mrpc_status_t expected;
	int expected_ioerrs=0;

	if (sem_init(&cb_complete, 0, 0))
		die("Couldn't initialize semaphore");
	sset=spawn_server(&set_port, proto_server, sync_server_accept, NULL,
				1);
	mrpc_set_disconnect_func(sset, disconnect_normal);
	mrpc_set_ioerr_func(sset, handle_ioerr);
	if (mrpc_conn_set_create(&cset, proto_client, NULL))
		die("Couldn't create client conn set");
	mrpc_set_disconnect_func(cset, disconnect_normal);
	mrpc_set_ioerr_func(cset, handle_ioerr);
	start_monitored_dispatcher(cset);

	cfd=socket(PF_INET, SOCK_STREAM, 0);
	if (cfd == -1)
		die("Couldn't create socket");
	addr.sin_family=AF_INET;
	addr.sin_port=htons(atoi(set_port));
	addr.sin_addr.s_addr=htonl(INADDR_LOOPBACK);
	if (connect(cfd, (struct sockaddr *)&addr, sizeof(addr)))
		die("Couldn't connect socket");
	free(set_port);
	lfd=socket(PF_INET, SOCK_STREAM, 0);
	if (lfd == -1)
		die("Couldn't create socket");
	addr.sin_port=0;
	if (bind(lfd, (struct sockaddr *)&addr, sizeof(addr)))
		die("Couldn't bind socket");
	if (listen(lfd, 16))
		die("Couldn't listen on socket");
	addrlen=sizeof(addr);
	if (getsockname(lfd, (struct sockaddr *)&addr, &addrlen))
		die("Couldn't get socket name");
	snprintf(skt_port, sizeof(skt_port), "%u", ntohs(addr.sin_port));
	if (mrpc_conn_create(&conn, cset, NULL))
		die("Couldn't create conn handle");
	if (mrpc_connect(conn, AF_INET, NULL, skt_port))
		die("Couldn't connect to listening socket");
	sfd=accept(lfd, NULL, NULL);
	if (sfd == -1)
		die("Couldn't accept incoming connection");
	close(lfd);

	/* Successful ping on raw client */
	send_msg(cfd, 0, MINIRPC_PENDING, nr_proto_ping, 0);
	recv_msg(cfd, &seq, MINIRPC_OK, nr_proto_ping, 0);
	expect(seq, 0);

	/* Successful ping on raw server */
	expected=0;
	expect(proto_ping_async(conn, cb_ping, &expected), 0);
	recv_msg(sfd, &seq, MINIRPC_PENDING, nr_proto_ping, 0);
	send_msg(sfd, seq, MINIRPC_OK, nr_proto_ping, 0);
	sem_wait(&cb_complete);

	/* Request payload too short */
	send_msg(cfd, 1, MINIRPC_PENDING, nr_proto_send_buffer, 500);
	recv_msg(cfd, &seq, MINIRPC_ENCODING_ERR, nr_proto_send_buffer, 0);
	expect(seq, 1);
	expected_ioerrs++;

	/* Request payload too long */
	send_msg(cfd, 2, MINIRPC_PENDING, nr_proto_send_buffer, 2000);
	recv_msg(cfd, &seq, MINIRPC_ENCODING_ERR, nr_proto_send_buffer, 0);
	expect(seq, 2);
	expected_ioerrs++;

	/* Zero-length request payload when expecting non-zero */
	send_msg(cfd, 3, MINIRPC_PENDING, nr_proto_send_buffer, 0);
	recv_msg(cfd, &seq, MINIRPC_ENCODING_ERR, nr_proto_send_buffer, 0);
	expect(seq, 3);
	expected_ioerrs++;

	/* Bogus procedure */
	send_msg(cfd, 4, MINIRPC_PENDING, 12345, 500);
	recv_msg(cfd, &seq, MINIRPC_PROCEDURE_UNAVAIL, 12345, 0);
	expect(seq, 4);

	/* Procedure call against NULL operations pointer */
	send_msg(sfd, 5, MINIRPC_PENDING, nr_proto_client_check_int, 4);
	recv_msg(sfd, &seq, MINIRPC_PROCEDURE_UNAVAIL,
				nr_proto_client_check_int, 0);
	expect(seq, 5);

	/* Call against procedure zero */
	send_msg(cfd, 6, MINIRPC_PENDING, 0, 0);
	recv_msg(cfd, &seq, MINIRPC_PROCEDURE_UNAVAIL, 0, 0);
	expect(seq, 6);

	/* Reply payload too short */
	expected=MINIRPC_ENCODING_ERR;
	expect(proto_recv_buffer_async(conn, cb_recv, &expected), 0);
	recv_msg(sfd, &seq, MINIRPC_PENDING, nr_proto_recv_buffer, 0);
	send_msg(sfd, seq, MINIRPC_OK, nr_proto_recv_buffer, 500);
	sem_wait(&cb_complete);
	expected_ioerrs++;

	/* Reply payload too long */
	expected=MINIRPC_ENCODING_ERR;
	expect(proto_recv_buffer_async(conn, cb_recv, &expected), 0);
	recv_msg(sfd, &seq, MINIRPC_PENDING, nr_proto_recv_buffer, 0);
	send_msg(sfd, seq, MINIRPC_OK, nr_proto_recv_buffer, 2000);
	sem_wait(&cb_complete);
	expected_ioerrs++;

	/* Zero-length reply payload when expecting nonzero */
	expected=MINIRPC_ENCODING_ERR;
	expect(proto_recv_buffer_async(conn, cb_recv, &expected), 0);
	recv_msg(sfd, &seq, MINIRPC_PENDING, nr_proto_recv_buffer, 0);
	send_msg(sfd, seq, MINIRPC_OK, nr_proto_recv_buffer, 0);
	sem_wait(&cb_complete);
	expected_ioerrs++;

	/* Successful recv_buffer call (sanity check) */
	expected=MINIRPC_OK;
	expect(proto_recv_buffer_async(conn, cb_recv, &expected), 0);
	recv_msg(sfd, &seq, MINIRPC_PENDING, nr_proto_recv_buffer, 0);
	send_msg(sfd, seq, MINIRPC_OK, nr_proto_recv_buffer, 1024);
	sem_wait(&cb_complete);

	/* Reply with both error code and payload */
	expected=MINIRPC_ENCODING_ERR;
	expect(proto_recv_buffer_async(conn, cb_recv, &expected), 0);
	recv_msg(sfd, &seq, MINIRPC_PENDING, nr_proto_recv_buffer, 0);
	send_msg(sfd, seq, 25, nr_proto_recv_buffer, 1024);
	sem_wait(&cb_complete);
	expected_ioerrs++;

	/* Reply with command not matching request command */
	expected=MINIRPC_ENCODING_ERR;
	expect(proto_ping_async(conn, cb_ping, &expected), 0);
	recv_msg(sfd, &seq, MINIRPC_PENDING, nr_proto_ping, 0);
	send_msg(sfd, seq, MINIRPC_OK, nr_proto_send_buffer, 0);
	sem_wait(&cb_complete);
	expected_ioerrs++;

	/* Unmatched reply */
	send_msg(cfd, 7, MINIRPC_OK, nr_proto_ping, 0);
	expected_ioerrs++;

	/* Unidirectional message with error code */
	send_msg(cfd, 8, MINIRPC_OK, nr_proto_msg_buffer, 1024);
	expected_ioerrs++;

	/* Empty event queues before closing, to make sure that no ioerr
	   events are squashed */
	send_msg(cfd, 0, MINIRPC_PENDING, nr_proto_ping, 0);
	recv_msg(cfd, &seq, MINIRPC_OK, nr_proto_ping, 0);
	expect(seq, 0);
	expected=0;
	expect(proto_ping_async(conn, cb_ping, &expected), 0);
	recv_msg(sfd, &seq, MINIRPC_PENDING, nr_proto_ping, 0);
	send_msg(sfd, seq, MINIRPC_OK, nr_proto_ping, 0);
	sem_wait(&cb_complete);

	close(cfd);
	close(sfd);
	mrpc_listen_close(sset);
	mrpc_conn_set_unref(sset);
	mrpc_conn_set_unref(cset);
	expect_disconnects(0, 2, 0);
	expect_ioerrs(expected_ioerrs);
	sem_destroy(&cb_complete);
	return 0;
}
Пример #17
0
/* non-SSL begin() function. */
static int begin(ne_socket **sock, server_fn fn, void *ud)
{
    CALL(spawn_server(7777, fn, ud));
    return do_connect(sock, localhost, 7777);
}
Пример #18
0
SPDConnection*
spd_open2(const char* client_name, const char* connection_name, const char* user_name,
	  SPDConnectionMode mode, SPDConnectionAddress *address, int autospawn,
	  char **error_result)
{
    SPDConnection *connection;
    char *set_client_name;
    char* conn_name;
    char* usr_name;
    int ret;
    char tcp_no_delay = 1;

    /* Autospawn related */
    int spawn_err;
    gchar *spawn_report;
    char *host_ip;
    int is_localhost = 1;
    
    struct sockaddr_in address_inet;    
    struct sockaddr_un address_unix;    
    struct sockaddr *sock_address;
    size_t sock_address_len;
    gchar *resolve_error;

    _init_debug();

    if (client_name == NULL){
      *error_result = strdup("ERROR: Client name not specified");
      SPD_DBG(*error_result);
      return NULL;
    }
    
    if (user_name == NULL)
    {
        usr_name = strdup((char*) g_get_user_name());
    }
    else
        usr_name = strdup(user_name);
    
    if(connection_name == NULL)
        conn_name = strdup("main");
    else
        conn_name = strdup(connection_name);

    if (address == NULL){
      char *err = NULL;
      address = spd_get_default_address(&err);
      if (!address){
	assert(err);
	*error_result = err;
	SPD_DBG(*error_result);
	return NULL;
      }
    }
    
    /* Connect to server using the selected method */
    connection = xmalloc(sizeof(SPDConnection));
    if (address->method==SPD_METHOD_INET_SOCKET){    
	host_ip = resolve_host(address->inet_socket_host, &is_localhost, &resolve_error);
	if (host_ip == NULL){
	    *error_result = strdup(resolve_error);
	    g_free(resolve_error);
	    return NULL;
	}	
	address_inet.sin_addr.s_addr = inet_addr(host_ip);
	address_inet.sin_port = htons(address->inet_socket_port);
	address_inet.sin_family = AF_INET;
	connection->socket = socket(AF_INET, SOCK_STREAM, 0);
	sock_address = (struct sockaddr*) &address_inet;
	sock_address_len = sizeof(address_inet);
    }else if (address->method==SPD_METHOD_UNIX_SOCKET){
      /* Create the unix socket */
      address_unix.sun_family = AF_UNIX;
      strncpy (address_unix.sun_path, address->unix_socket_name, sizeof (address_unix.sun_path));
      address_unix.sun_path[sizeof (address_unix.sun_path) - 1] = '\0';
      connection->socket = socket(AF_UNIX, SOCK_STREAM, 0);
      sock_address = (struct sockaddr*) &address_unix;
      sock_address_len = SUN_LEN(&address_unix);
    }else SPD_FATAL("Unsupported connection method for spd_open2()");

    ret = connect(connection->socket, sock_address, sock_address_len);    
    if (ret == -1){
	/* Suppose server might not be running, try to autospawn (autostart) it */
	if (autospawn){	
	    spawn_err = spawn_server(address, is_localhost, &spawn_report);
	    if (!spawn_err)
		spawn_report = g_strdup("Server successfully autospawned");
	    ret = connect(connection->socket, sock_address, sock_address_len);    
	}else{
	    spawn_report = g_strdup("Autospawn disabled");
	}
	if (ret == -1){
	    if (address->method == SPD_METHOD_INET_SOCKET)
		*error_result = g_strdup_printf("Error: Can't connect to %s on port %d using inet sockets: %s. " \
						"Autospawn: %s", address->inet_socket_host,
						address->inet_socket_port, strerror(errno), spawn_report);
	    else if (address->method == SPD_METHOD_UNIX_SOCKET)
		*error_result = g_strdup_printf("Error: Can't connect to unix socket %s: %s. Autospawn: %s",
						address->unix_socket_name, strerror(errno), spawn_report);
	    else assert (0);
	    SPD_DBG(*error_result);
	    close(connection->socket);	
	    return NULL;
	}
    }

    if (address->method == SPD_METHOD_INET_SOCKET)
	setsockopt(connection->socket, IPPROTO_TCP, TCP_NODELAY, &tcp_no_delay, sizeof(int));
    
    connection->callback_begin = NULL;
    connection->callback_end = NULL;
    connection->callback_im = NULL;
    connection->callback_pause = NULL;
    connection->callback_resume = NULL;
    connection->callback_cancel = NULL;

    connection->mode = mode;

    /* Create a stream from the socket */
    connection->stream = fdopen(connection->socket, "r");
    if (!connection->stream) SPD_FATAL("Can't create a stream for socket, fdopen() failed.");
    /* Switch to line buffering mode */
    ret = setvbuf(connection->stream, NULL, _IONBF, SPD_REPLY_BUF_SIZE);
    if (ret) SPD_FATAL("Can't set buffering, setvbuf failed.");

    connection->ssip_mutex = xmalloc(sizeof(pthread_mutex_t));
    pthread_mutex_init(connection->ssip_mutex, NULL);

    if (mode == SPD_MODE_THREADED){
	SPD_DBG("Initializing threads, condition variables and mutexes...");
	connection->events_thread = xmalloc(sizeof(pthread_t));
	connection->cond_reply_ready = xmalloc(sizeof(pthread_cond_t));
	connection->mutex_reply_ready = xmalloc(sizeof(pthread_mutex_t));
	connection->cond_reply_ack = xmalloc(sizeof(pthread_cond_t));
	connection->mutex_reply_ack = xmalloc(sizeof(pthread_mutex_t));
	pthread_cond_init(connection->cond_reply_ready, NULL);
	pthread_mutex_init(connection->mutex_reply_ready, NULL);
	pthread_cond_init(connection->cond_reply_ack, NULL);
	pthread_mutex_init(connection->mutex_reply_ack, NULL);
	ret = pthread_create(connection->events_thread, NULL, spd_events_handler, connection);
	if(ret != 0){
	    *error_result = strdup("Thread initialization failed");
	    SPD_DBG(*error_result);
	    return NULL;
	}
    }

    /* By now, the connection is created and operational */
    set_client_name = g_strdup_printf("SET SELF CLIENT_NAME \"%s:%s:%s\"", usr_name,
				      client_name, conn_name);
    ret = spd_execute_command_wo_mutex(connection, set_client_name);   
    xfree(usr_name);  xfree(conn_name);  xfree(set_client_name);
    return connection;
}
Пример #19
0
int main(int argc, char **argv)
{
	struct mrpc_conn_set *sset;
	struct mrpc_conn_set *cset;
	struct mrpc_connection *conn;
	char *port;
	int ret;
	int i;

	sset=spawn_server(&port, proto_server, sync_server_accept, NULL, 1);
	mrpc_set_disconnect_func(sset, disconnect_normal);

	if (mrpc_conn_set_create(&cset, proto_client, NULL))
		die("Couldn't create conn set");
	mrpc_set_disconnect_func(cset, disconnect_user);
	start_monitored_dispatcher(cset);

	/* Try repeated connections from the same conn set */
	for (i=0; i<500; i++) {
		ret=mrpc_conn_create(&conn, cset, NULL);
		if (ret)
			die("%s in mrpc_conn_create() on iteration %d",
						strerror(ret), i);
		ret=mrpc_connect(conn, AF_UNSPEC, "localhost", port);
		if (ret)
			die("%s in mrpc_connect() on iteration %d",
						strerror(ret), i);
		sync_client_set_ops(conn);
		sync_client_run(conn);
		mrpc_conn_close(conn);
		mrpc_conn_unref(conn);
	}
	mrpc_conn_set_unref(cset);

	/* Try repeated connections from different conn sets */
	for (i=0; i<100; i++) {
		if (mrpc_conn_set_create(&cset, proto_client, NULL))
			die("Couldn't create conn set");
		mrpc_set_disconnect_func(cset, disconnect_user);
		start_monitored_dispatcher(cset);

		ret=mrpc_conn_create(&conn, cset, NULL);
		if (ret)
			die("%s in mrpc_conn_create() on iteration %d",
						strerror(ret), i);
		ret=mrpc_connect(conn, AF_UNSPEC, "localhost", port);
		if (ret)
			die("%s in mrpc_connect() on iteration %d",
						strerror(ret), i);
		sync_client_set_ops(conn);
		sync_client_run(conn);
		mrpc_conn_close(conn);
		mrpc_conn_unref(conn);
		mrpc_conn_set_unref(cset);
	}

	mrpc_listen_close(sset);
	mrpc_conn_set_unref(sset);
	expect_disconnects(600, 600, 0);
	free(port);
	return 0;
}
Пример #20
0
static int client(apr_pool_t *p, client_socket_mode_t socket_mode,
                  const char *host, int start_server)
{
    apr_status_t rv, tmprv;
    apr_socket_t *sock;
    char buf[120];
    apr_file_t *f = NULL;
    apr_size_t len;
    apr_size_t expected_len;
    apr_off_t current_file_offset;
    apr_hdtr_t hdtr;
    struct iovec headers[3];
    struct iovec trailers[3];
    apr_size_t bytes_read;
    apr_pollset_t *pset;
    apr_int32_t nsocks;
    int connect_tries = 1;
    int i;
    int family;
    apr_sockaddr_t *destsa;
    apr_proc_t server;
    apr_interval_time_t connect_retry_interval = apr_time_from_msec(50);

    if (start_server) {
        spawn_server(p, &server);
        connect_tries = 5; /* give it a chance to start up */
    }

    create_testfile(p, TESTFILE);

    rv = apr_file_open(&f, TESTFILE, APR_FOPEN_READ, 0, p);
    if (rv != APR_SUCCESS) {
        aprerr("apr_file_open()", rv);
    }

    if (!host) {
        host = "127.0.0.1";
    }
    family = APR_INET;
    rv = apr_sockaddr_info_get(&destsa, host, family, TESTSF_PORT, 0, p);
    if (rv != APR_SUCCESS) {
        aprerr("apr_sockaddr_info_get()", rv);
    }

    while (connect_tries--) {
        apr_setup(p, &sock, &family);
        rv = apr_socket_connect(sock, destsa);
        if (connect_tries && APR_STATUS_IS_ECONNREFUSED(rv)) {
            apr_status_t tmprv = apr_socket_close(sock);
            if (tmprv != APR_SUCCESS) {
                aprerr("apr_socket_close()", tmprv);
            }
            apr_sleep(connect_retry_interval);
            connect_retry_interval *= 2;
        }
        else {
            break;
        }
    }
    if (rv != APR_SUCCESS) {
        aprerr("apr_socket_connect()", rv);
    }

    switch(socket_mode) {
    case BLK:
        /* leave it blocking */
        break;
    case NONBLK:
        /* set it non-blocking */
        rv = apr_socket_opt_set(sock, APR_SO_NONBLOCK, 1);
        if (rv != APR_SUCCESS) {
            aprerr("apr_socket_opt_set(APR_SO_NONBLOCK)", rv);
        }
        break;
    case TIMEOUT:
        /* set a timeout */
        rv = apr_socket_timeout_set(sock, 100 * APR_USEC_PER_SEC);
        if (rv != APR_SUCCESS) {
            aprerr("apr_socket_opt_set(APR_SO_NONBLOCK)", rv);
            exit(1);
        }
        break;
    default:
        assert(1 != 1);
    }

    printf("Sending the file...\n");

    hdtr.headers = headers;
    hdtr.numheaders = 3;
    hdtr.headers[0].iov_base = HDR1;
    hdtr.headers[0].iov_len  = strlen(hdtr.headers[0].iov_base);
    hdtr.headers[1].iov_base = HDR2;
    hdtr.headers[1].iov_len  = strlen(hdtr.headers[1].iov_base);
    hdtr.headers[2].iov_base = malloc(HDR3_LEN);
    assert(hdtr.headers[2].iov_base);
    memset(hdtr.headers[2].iov_base, HDR3_CHAR, HDR3_LEN);
    hdtr.headers[2].iov_len  = HDR3_LEN;

    hdtr.trailers = trailers;
    hdtr.numtrailers = 3;
    hdtr.trailers[0].iov_base = TRL1;
    hdtr.trailers[0].iov_len  = strlen(hdtr.trailers[0].iov_base);
    hdtr.trailers[1].iov_base = TRL2;
    hdtr.trailers[1].iov_len  = strlen(hdtr.trailers[1].iov_base);
    hdtr.trailers[2].iov_base = malloc(TRL3_LEN);
    memset(hdtr.trailers[2].iov_base, TRL3_CHAR, TRL3_LEN);
    assert(hdtr.trailers[2].iov_base);
    hdtr.trailers[2].iov_len  = TRL3_LEN;

    expected_len = 
        strlen(HDR1) + strlen(HDR2) + HDR3_LEN +
        strlen(TRL1) + strlen(TRL2) + TRL3_LEN +
        FILE_LENGTH;
    
    if (socket_mode == BLK) {
        current_file_offset = 0;
        len = FILE_LENGTH;
        rv = apr_socket_sendfile(sock, f, &hdtr, &current_file_offset, &len, 0);
        if (rv != APR_SUCCESS) {
            aprerr("apr_socket_sendfile()", rv);
        }
        
        printf("apr_socket_sendfile() updated offset with %ld\n",
               (long int)current_file_offset);
        
        printf("apr_socket_sendfile() updated len with %ld\n",
               (long int)len);
        
        printf("bytes really sent: %" APR_SIZE_T_FMT "\n",
               expected_len);

        if (len != expected_len) {
            fprintf(stderr, "apr_socket_sendfile() didn't report the correct "
                    "number of bytes sent!\n");
            exit(1);
        }
    }
    else {
        /* non-blocking... wooooooo */
        apr_size_t total_bytes_sent;
        apr_pollfd_t pfd;

        pset = NULL;
        rv = apr_pollset_create(&pset, 1, p, 0);
        assert(!rv);
        pfd.p = p;
        pfd.desc_type = APR_POLL_SOCKET;
        pfd.reqevents = APR_POLLOUT;
        pfd.rtnevents = 0;
        pfd.desc.s = sock;
        pfd.client_data = NULL;

        rv = apr_pollset_add(pset, &pfd);        
        assert(!rv);

        total_bytes_sent = 0;
        current_file_offset = 0;
        len = FILE_LENGTH;
        do {
            apr_size_t tmplen;

            tmplen = len; /* bytes remaining to send from the file */
            printf("Calling apr_socket_sendfile()...\n");
            printf("Headers (%d):\n", hdtr.numheaders);
            for (i = 0; i < hdtr.numheaders; i++) {
                printf("\t%ld bytes (%c)\n",
                       (long)hdtr.headers[i].iov_len,
                       *(char *)hdtr.headers[i].iov_base);
            }
            printf("File: %ld bytes from offset %ld\n",
                   (long)tmplen, (long)current_file_offset);
            printf("Trailers (%d):\n", hdtr.numtrailers);
            for (i = 0; i < hdtr.numtrailers; i++) {
                printf("\t%ld bytes\n",
                       (long)hdtr.trailers[i].iov_len);
            }

            rv = apr_socket_sendfile(sock, f, &hdtr, &current_file_offset, &tmplen, 0);
            printf("apr_socket_sendfile()->%d, sent %ld bytes\n", rv, (long)tmplen);
            if (rv) {
                if (APR_STATUS_IS_EAGAIN(rv)) {
                    assert(tmplen == 0);
                    nsocks = 1;
                    tmprv = apr_pollset_poll(pset, -1, &nsocks, NULL);
                    assert(!tmprv);
                    assert(nsocks == 1);
                    /* continue; */
                }
            }

            total_bytes_sent += tmplen;

            /* Adjust hdtr to compensate for partially-written
             * data.
             */

            /* First, skip over any header data which might have
             * been written.
             */
            while (tmplen && hdtr.numheaders) {
                if (tmplen >= hdtr.headers[0].iov_len) {
                    tmplen -= hdtr.headers[0].iov_len;
                    --hdtr.numheaders;
                    ++hdtr.headers;
                }
                else {
                    hdtr.headers[0].iov_len -= tmplen;
                    hdtr.headers[0].iov_base = 
			(char*) hdtr.headers[0].iov_base + tmplen;
                    tmplen = 0;
                }
            }

            /* Now, skip over any file data which might have been
             * written.
             */

            if (tmplen <= len) {
                current_file_offset += tmplen;
                len -= tmplen;
                tmplen = 0;
            }
            else {
                tmplen -= len;
                len = 0;
                current_file_offset = 0;
            }

            /* Last, skip over any trailer data which might have
             * been written.
             */

            while (tmplen && hdtr.numtrailers) {
                if (tmplen >= hdtr.trailers[0].iov_len) {
                    tmplen -= hdtr.trailers[0].iov_len;
                    --hdtr.numtrailers;
                    ++hdtr.trailers;
                }
                else {
                    hdtr.trailers[0].iov_len -= tmplen;
                    hdtr.trailers[0].iov_base = 
			(char *)hdtr.trailers[0].iov_base + tmplen;
                    tmplen = 0;
                }
            }

        } while (total_bytes_sent < expected_len &&
                 (rv == APR_SUCCESS || 
                 (APR_STATUS_IS_EAGAIN(rv) && socket_mode != TIMEOUT)));
        if (total_bytes_sent != expected_len) {
            fprintf(stderr,
                    "client problem: sent %ld of %ld bytes\n",
                    (long)total_bytes_sent, (long)expected_len);
            exit(1);
        }

        if (rv) {
            fprintf(stderr,
                    "client problem: rv %d\n",
                    rv);
            exit(1);
        }
    }
    
    current_file_offset = 0;
    rv = apr_file_seek(f, APR_CUR, &current_file_offset);
    if (rv != APR_SUCCESS) {
        aprerr("apr_file_seek()", rv);
    }

    printf("After apr_socket_sendfile(), the kernel file pointer is "
           "at offset %ld.\n",
           (long int)current_file_offset);

    rv = apr_socket_shutdown(sock, APR_SHUTDOWN_WRITE);
    if (rv != APR_SUCCESS) {
        aprerr("apr_socket_shutdown()", rv);
    }

    /* in case this is the non-blocking test, set socket timeout;
     * we're just waiting for EOF */

    rv = apr_socket_timeout_set(sock, apr_time_from_sec(3));
    if (rv != APR_SUCCESS) {
        aprerr("apr_socket_timeout_set()", rv);
    }
    
    bytes_read = 1;
    rv = apr_socket_recv(sock, buf, &bytes_read);
    if (rv != APR_EOF) {
        aprerr("apr_socket_recv() (expected APR_EOF)", rv);
    }
    if (bytes_read != 0) {
        fprintf(stderr, "We expected to get 0 bytes read with APR_EOF\n"
                "but instead we read %ld bytes.\n",
                (long int)bytes_read);
        exit(1);
    }

    printf("client: apr_socket_sendfile() worked as expected!\n");

    rv = apr_file_remove(TESTFILE, p);
    if (rv != APR_SUCCESS) {
        aprerr("apr_file_remove()", rv);
    }

    if (start_server) {
        apr_exit_why_e exitwhy;
        apr_size_t nbytes;
        char responsebuf[1024];
        int exitcode;

        rv = apr_file_pipe_timeout_set(server.out, apr_time_from_sec(2));
        if (rv != APR_SUCCESS) {
            aprerr("apr_file_pipe_timeout_set()", rv);
        }
        nbytes = sizeof(responsebuf);
        rv = apr_file_read(server.out, responsebuf, &nbytes);
        if (rv != APR_SUCCESS) {
            aprerr("apr_file_read() messages from server", rv);
        }
        printf("%.*s", (int)nbytes, responsebuf);
        rv = apr_proc_wait(&server, &exitcode, &exitwhy, APR_WAIT);
        if (rv != APR_CHILD_DONE) {
            aprerr("apr_proc_wait() (expected APR_CHILD_DONE)", rv);
        }
        if (exitcode != 0) {
            fprintf(stderr, "sendfile server returned %d\n", exitcode);
            exit(1);
        }
    }

    return 0;
}