Exemple #1
0
/*
 * Close the sockets, shutdown the server and exit.
 * Does not return.
 *
 */
static void
server_shutdown(struct nsd *nsd)
{
	size_t i;

	close_all_sockets(nsd->udp, nsd->ifs);
	close_all_sockets(nsd->tcp, nsd->ifs);
	/* CHILD: close command channel to parent */
	if(nsd->this_child && nsd->this_child->parent_fd != -1)
	{
		close(nsd->this_child->parent_fd);
		nsd->this_child->parent_fd = -1;
	}
	/* SERVER: close command channels to children */
	if(!nsd->this_child)
	{
		for(i=0; i < nsd->child_count; ++i)
			if(nsd->children[i].child_fd != -1)
			{
				close(nsd->children[i].child_fd);
				nsd->children[i].child_fd = -1;
			}
	}

	log_finalize();
	tsig_finalize();

	nsd_options_destroy(nsd->options);
	region_destroy(nsd->region);

	exit(0);
}
Exemple #2
0
// TODO: BUG: The Peak on Windows rarely doesn't close the input thread.
//   This causes the UI thread to hang on exit.
void *input_thread(void *_t, struct dll_io_bridge * _io_bridge)
{
    i_bridge = _io_bridge;

    atransport *t = (atransport *)_t;
    apacket *p;
    int active = 0;

    D("%s: starting transport input thread, reading from fd %d\n",
       t->serial, t->fd);

    for(;;){
        if(read_packet(t->fd, t->serial, &p)) {
            D("%s: failed to read apacket from transport on fd %d\n",
               t->serial, t->fd );
            break;
        }
        if(p->msg.command == A_SYNC){
            if(p->msg.arg0 == 0) {
                D("%s: transport SYNC offline\n", t->serial);
                put_apacket(p);
                break;
            } else {
                if(p->msg.arg1 == t->sync_token) {
                    D("%s: transport SYNC online\n", t->serial);
                    active = 1;
                } else {
                    D("%s: transport ignoring SYNC %d != %d\n",
                      t->serial, p->msg.arg1, t->sync_token);
                }
            }
        } else {
            if(active) {
                D("%s: transport got packet %d, sending to remote\n", t->serial, p->msg.command);
                t->write_to_remote(p, t);
            } else {
                D("%s: transport ignoring packet while offline\n", t->serial);
            }
        }

        put_apacket(p);
    }

    // this is necessary to avoid a race condition that occured when a transport closes
    // while a client socket is still active.
	D("Pre-close sockets input-thread\n");
    close_all_sockets(t);

    D("%s: transport input thread is exiting, fd %d\n", t->serial, t->fd);
#ifdef WIN32
    kick_transport(t, i_bridge->AdbCloseHandle);
#else
    kick_transport(t, NULL);
#endif
	D("Post-kick transport input-thread\n");
    transport_unref(t);
	D("Post-unref transport input-thread\n");

    return 0;
}
Exemple #3
0
/* nap_exit: cleans up and leaves */
void nap_exit (int really_quit, char *reason, char *format, ...)
{
	if (dead == 1) {
		kill_all_threads();
		exit(1);
	}
	else if (dead == 2) {
		kill_all_threads();
		_exit(1);
	}
	else if (dead == 3) {
		kill_all_threads();
		kill(getpid(), SIGKILL);
	}
	dead++;

	set_lastlog_size(NULL, NULL, 0);
	set_history_size(NULL, NULL, 0);

	if (really_quit)
	{
		kill_all_threads();
		say("Signon time  :    %s", my_ctime(start_time));
		say("Signoff time :    %s", my_ctime(now));
		say("Total uptime :    %s", convert_time(now - start_time));
	}
	do_hook(EXIT_LIST, "%s", reason ? reason : empty_string);
	if (reason)
		say("%s", reason);

	close_all_servers();
	close_all_sockets();
	if (term_initialized)
	{
		cursor_to_input();
		term_cr();
		term_clear_to_eol();
		term_reset();
	}

	remove_bindings();
	clear_variables();
	delete_all_windows();
	destroy_call_stack();		
	write_unfinished_list();
	
	debug_cleanup();
	fprintf(stdout, "\r");
	fflush(stdout);
	if (really_quit)
		exit(0);

	kill_all_threads();
	my_signal(SIGABRT, SIG_DFL, 0);
	kill(getpid(), SIGABRT);
	kill(getpid(), SIGQUIT);
	exit(1);
}
static void *input_thread(void *_t)
{
    atransport *t = reinterpret_cast<atransport*>(_t);
    apacket *p;
    int active = 0;

    ADB_LOGD(ADB_TSPT,
             "%s: starting transport input thread, reading from fd %d",
             t->serial, t->fd);

    for (;;) {
        if (read_packet(t->fd, t->serial, &p)) {
            ADB_LOGE(ADB_TSPT,
                     "%s: failed to read apacket from transport on fd %d",
                     t->serial, t->fd);
            break;
        }
        if (p->msg.command == A_SYNC) {
            if (p->msg.arg0 == 0) {
                ADB_LOGE(ADB_TSPT, "%s: transport SYNC offline", t->serial);
                put_apacket(p);
                break;
            } else {
                if (p->msg.arg1 == t->sync_token) {
                    ADB_LOGD(ADB_TSPT, "%s: transport SYNC online", t->serial);
                    active = 1;
                } else {
                    ADB_LOGD(ADB_TSPT, "%s: transport ignoring SYNC %d != %d",
                             t->serial, p->msg.arg1, t->sync_token);
                }
            }
        } else {
            if (active) {
                ADB_LOGD(ADB_TSPT,
                         "%s: transport got packet, sending to remote",
                         t->serial);
                t->write_to_remote(p, t);
            } else {
                ADB_LOGD(ADB_TSPT,
                         "%s: transport ignoring packet while offline",
                         t->serial);
            }
        }

        put_apacket(p);
    }

    // this is necessary to avoid a race condition that occured when a transport closes
    // while a client socket is still active.
    close_all_sockets(t);

    ADB_LOGD(ADB_TSPT, "%s: transport input thread is exiting, fd %d",
             t->serial, t->fd);
    kick_transport(t);
    transport_unref(t);
    return 0;
}
void handle_offline(atransport *t)
{
    D("adb: offline");
    //Close the associated usb
    t->online = 0;

    // This is necessary to avoid a race condition that occurred when a transport closes
    // while a client socket is still active.
    close_all_sockets(t);

    t->RunDisconnects();
}
static void *input_thread(void *_t)
{
    atransport *t = _t;
    apacket *p;
    int active = 0;

    D("to_remote: starting input_thread for %p, reading from fd %d\n",
       t, t->fd);

    for(;;){
        if(read_packet(t->fd, &p)) {
            D("to_remote: failed to read apacket from transport %p on fd %d\n", 
               t, t->fd );
            break;
        }
        if(p->msg.command == A_SYNC){
            if(p->msg.arg0 == 0) {
                D("to_remote: transport %p SYNC offline\n", t);
                put_apacket(p);
                break;
            } else {
                if(p->msg.arg1 == t->sync_token) {
                    D("to_remote: transport %p SYNC online\n", t);
                    active = 1;
                } else {
                    D("to_remote: trandport %p ignoring SYNC %d != %d\n",
                      t, p->msg.arg1, t->sync_token);
                }
            }
        } else {
            if(active) {
                D("to_remote: transport %p got packet, sending to remote\n", t);
                t->write_to_remote(p, t);
            } else {
                D("to_remote: transport %p ignoring packet while offline\n", t);
            }
        }

        put_apacket(p);
    }

    // this is necessary to avoid a race condition that occured when a transport closes
    // while a client socket is still active.
    close_all_sockets(t);

    D("to_remote: thread is exiting for transport %p, fd %d\n", t, t->fd);
    kick_transport(t);
    transport_unref(t);
    return 0;
}
Exemple #7
0
void state_free(struct state *state)
{
	/* We have to stop the system call thread first, since it's using
	 * sockets that we want to close and reset.
	 */
	syscalls_free(state, state->syscalls);

	/* Then we close the sockets and reset the connections, while
	 * we still have a netdev for injecting reset packets to free
	 * per-connection kernel state.
	 */
	close_all_sockets(state);

	netdev_free(state->netdev);
	packets_free(state->packets);
	code_free(state->code);

	run_unlock(state);
	if (pthread_mutex_destroy(&state->mutex) != 0)
		die_perror("pthread_mutex_destroy");

	memset(state, 0, sizeof(*state));  /* paranoia to help catch bugs */
	free(state);
}
Exemple #8
0
/*
 * Serve DNS requests.
 */
void
server_child(struct nsd *nsd)
{
	size_t i;
	region_type *server_region = region_create(xalloc, free);
	netio_type *netio = netio_create(server_region);
	netio_handler_type *tcp_accept_handlers;
	query_type *udp_query;
	sig_atomic_t mode;

	assert(nsd->server_kind != NSD_SERVER_MAIN);
	DEBUG(DEBUG_IPC, 2, (LOG_INFO, "child process started"));

	if (!(nsd->server_kind & NSD_SERVER_TCP)) {
		close_all_sockets(nsd->tcp, nsd->ifs);
	}
	if (!(nsd->server_kind & NSD_SERVER_UDP)) {
		close_all_sockets(nsd->udp, nsd->ifs);
	}

	if (nsd->this_child && nsd->this_child->parent_fd != -1) {
		netio_handler_type *handler;

		handler = (netio_handler_type *) region_alloc(
			server_region, sizeof(netio_handler_type));
		handler->fd = nsd->this_child->parent_fd;
		handler->timeout = NULL;
		handler->user_data = (struct ipc_handler_conn_data*)region_alloc(
			server_region, sizeof(struct ipc_handler_conn_data));
		((struct ipc_handler_conn_data*)handler->user_data)->nsd = nsd;
		((struct ipc_handler_conn_data*)handler->user_data)->conn =
			xfrd_tcp_create(server_region);
		handler->event_types = NETIO_EVENT_READ;
		handler->event_handler = child_handle_parent_command;
		netio_add_handler(netio, handler);
	}

	if (nsd->server_kind & NSD_SERVER_UDP) {
		udp_query = query_create(server_region,
			compressed_dname_offsets, compression_table_size);

		for (i = 0; i < nsd->ifs; ++i) {
			struct udp_handler_data *data;
			netio_handler_type *handler;

			data = (struct udp_handler_data *) region_alloc(
				server_region,
				sizeof(struct udp_handler_data));
			data->query = udp_query;
			data->nsd = nsd;
			data->socket = &nsd->udp[i];

			handler = (netio_handler_type *) region_alloc(
				server_region, sizeof(netio_handler_type));
			handler->fd = nsd->udp[i].s;
			handler->timeout = NULL;
			handler->user_data = data;
			handler->event_types = NETIO_EVENT_READ;
			handler->event_handler = handle_udp;
			netio_add_handler(netio, handler);
		}
	}

	/*
	 * Keep track of all the TCP accept handlers so we can enable
	 * and disable them based on the current number of active TCP
	 * connections.
	 */
	tcp_accept_handlers = (netio_handler_type *) region_alloc(
		server_region, nsd->ifs * sizeof(netio_handler_type));
	if (nsd->server_kind & NSD_SERVER_TCP) {
		for (i = 0; i < nsd->ifs; ++i) {
			struct tcp_accept_handler_data *data;
			netio_handler_type *handler;

			data = (struct tcp_accept_handler_data *) region_alloc(
				server_region,
				sizeof(struct tcp_accept_handler_data));
			data->nsd = nsd;
			data->socket = &nsd->tcp[i];
			data->tcp_accept_handler_count = nsd->ifs;
			data->tcp_accept_handlers = tcp_accept_handlers;

			handler = &tcp_accept_handlers[i];
			handler->fd = nsd->tcp[i].s;
			handler->timeout = NULL;
			handler->user_data = data;
			handler->event_types = NETIO_EVENT_READ | NETIO_EVENT_ACCEPT;
			handler->event_handler = handle_tcp_accept;
			netio_add_handler(netio, handler);
		}
	}

	/* The main loop... */
	while ((mode = nsd->mode) != NSD_QUIT) {
		if(mode == NSD_RUN) nsd->mode = mode = server_signal_mode(nsd);

		/* Do we need to do the statistics... */
		if (mode == NSD_STATS) {
#ifdef BIND8_STATS
			/* Dump the statistics */
			bind8_stats(nsd);
#else /* !BIND8_STATS */
			log_msg(LOG_NOTICE, "Statistics support not enabled at compile time.");
#endif /* BIND8_STATS */

			nsd->mode = NSD_RUN;
		}
		else if (mode == NSD_REAP_CHILDREN) {
			/* got signal, notify parent. parent reaps terminated children. */
			if (nsd->this_child->parent_fd != -1) {
				sig_atomic_t parent_notify = NSD_REAP_CHILDREN;
				if (write(nsd->this_child->parent_fd,
				    &parent_notify,
				    sizeof(parent_notify)) == -1)
				{
					log_msg(LOG_ERR, "problems sending command from %d to parent: %s",
						(int) nsd->this_child->pid, strerror(errno));
				}
			} else /* no parent, so reap 'em */
				while (waitpid(0, NULL, WNOHANG) > 0) ;
			nsd->mode = NSD_RUN;
		}
		else if(mode == NSD_RUN) {
			/* Wait for a query... */
			if (netio_dispatch(netio, NULL, NULL) == -1) {
				if (errno != EINTR) {
					log_msg(LOG_ERR, "netio_dispatch failed: %s", strerror(errno));
					break;
				}
			}
		} else if(mode == NSD_QUIT) {
			/* ignore here, quit */
		} else {
			log_msg(LOG_ERR, "mode bad value %d, back to service.",
				mode);
			nsd->mode = NSD_RUN;
		}
	}

#ifdef	BIND8_STATS
	bind8_stats(nsd);
#endif /* BIND8_STATS */

	namedb_fd_close(nsd->db);
	region_destroy(server_region);
	server_shutdown(nsd);
}
Exemple #9
0
void signal_handler(int signal_number) {
	if (state != NULL)
		close_all_sockets(state);
	
	die("Handled signal %d\n", signal_number);
}