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); } } } }
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; }
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; }
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 ); }
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); }
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; }
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); }
/* 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; }
/* 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; }
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; }
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; }
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); }
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; }
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; }
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; }
/* 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); }
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; }
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; }
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, ¤t_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, ¤t_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, ¤t_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; }