static int
ssn_handler(TSCont contp, TSEvent event, void *edata)
{
  TSHttpSsn ssnp;
  TSHttpTxn txnp;

  switch (event) {
  case TS_EVENT_HTTP_SSN_START:

    ssnp = (TSHttpSsn)edata;
    handle_session(ssnp, contp);
    TSHttpSsnReenable(ssnp, TS_EVENT_HTTP_CONTINUE);
    return 0;

  case TS_EVENT_HTTP_TXN_START:
    txnp = (TSHttpTxn)edata;
    txn_handler(txnp, contp);
    TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE);
    return 0;

  default:
    TSDebug("tag_session", "In the default case: event = %d", event);
    break;
  }
  return 0;
}
Exemple #2
0
//--------------------------------------------------------------------------
// __try handler can't be placed in fuction which requires object unwinding
static void protected_privileged_session(IRAPIStream* pStream)
{
  try
  {
    idarpc_stream_t *irs = init_server_irs(pStream);
    if ( irs == NULL )
      return;

    rpc_server_t *server = new rpc_server_t(irs);
    server->verbose = verbose;
    server->set_debugger_instance(create_debug_session());

    static bool inited = false;
    if ( !inited )
    {
      inited = true;
      init_idc();
    }
    handle_session(server);
  }
  //__except ( display_exception(GetExceptionCode(), GetExceptionInformation()) )
  catch(...)
  {
  }
}
Exemple #3
0
NET_API int
net_wait(struct net_service* service, int timeout)
{
	int cnt;
	int wait_cnt;
	int i;
	int try_cnt;
	ffid_vtype id;
	struct epoll_event events[32];
	struct net_session* session;
	const struct sbtree_node* node;
	unsigned short index;


	cnt = 0;

	while((wait_cnt = epoll_wait(service->net_service_fd, events, sizeof(events)/sizeof(events[0]), timeout)))
	{
		if(wait_cnt < 0) return wait_cnt;
		cnt += wait_cnt;
		for(i = 0; i < wait_cnt; ++i)
		{

			id = (ffid_vtype)events[i].data.u64;
			if(!id) continue;
			index = ffid_index(service->socket_ids, id);

			net_lock(&service->session_lock[index]);
	
			session = service->sessions[index];
			if(!session || session->id != id)
			{
				//session delete from net_service
				net_lock(&service->close_lock);
				node = sb_tree_find(service->close_root, id);
				net_unlock(&service->close_lock);
				if(node)
				{
					session = (struct net_session*)node->value.ptr;
					handle_rest(service, session, events[i].events);
				}
				else
				{
					// cur thread get the id but threadB close session and no write op
				}
			}
			else
			{
				//session still in net_service
				handle_session(service, session, events[i].events);
			}
			net_unlock(&service->session_lock[index]);
		}
		
	}
	return cnt;
}
Exemple #4
0
void main(int argc, char *argv[])
{ 
  WSADATA wsadata;
  SOCKADDR_IN sin;
  int rc;

  // Parse arguments
  if (argc > 1)
    debuggee_port = argv[1];
  else
    debuggee_port = "COM1";

  // Initialize winsock
  rc = WSAStartup(MAKEWORD(2, 2), &wsadata);
  if (rc != 0) panic("error in WSAStartup");

  // Create listen socket
  listener = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
  if (listener == INVALID_SOCKET) panic("error in socket");

  // Bind the socket to the service port
  memset(&sin, 0, sizeof(sin));
  sin.sin_family = AF_INET;
  sin.sin_addr.s_addr = INADDR_ANY;
  sin.sin_port = htons(DEBUGGER_PORT);
  if (bind(listener, (LPSOCKADDR) &sin, sizeof(sin)) == SOCKET_ERROR) panic("error in bind");

  // Listen for incoming connections on the socket
  if (listen(listener, 5) == SOCKET_ERROR) panic("error in listen");

  printf("waiting for debugger...\n");

  // Wait and accept new connection from client
  while (1)
  {
    debugger = accept(listener, NULL, NULL);
    if (debugger == INVALID_SOCKET) panic("error in accept");

    handle_session();
  }

  closesocket(listener);
}
Exemple #5
0
static void *handle_connections(void *arg)
{
  st_netfd_t srv_nfd, cli_nfd;
  struct sockaddr_in from;
  int fromlen;
  long i = (long) arg;

  srv_nfd = srv_socket[i].nfd;
  fromlen = sizeof(from);

  while (WAIT_THREADS(i) <= max_wait_threads) {
    cli_nfd = st_accept(srv_nfd, (struct sockaddr *)&from, &fromlen,
     ST_UTIME_NO_TIMEOUT);
    if (cli_nfd == NULL) {
      err_sys_report(errfd, "ERROR: can't accept connection: st_accept");
      continue;
    }
    /* Save peer address, so we can retrieve it later */
    st_netfd_setspecific(cli_nfd, &from.sin_addr, NULL);

    WAIT_THREADS(i)--;
    BUSY_THREADS(i)++;
    if (WAIT_THREADS(i) < min_wait_threads && TOTAL_THREADS(i) < max_threads) {
      /* Create another spare thread */
      if (st_thread_create(handle_connections, (void *)i, 0, 0) != NULL)
	WAIT_THREADS(i)++;
      else
	err_sys_report(errfd, "ERROR: process %d (pid %d): can't create"
		       " thread", my_index, my_pid);
    }

    handle_session(i, cli_nfd);

    st_netfd_close(cli_nfd);
    WAIT_THREADS(i)++;
    BUSY_THREADS(i)--;
  }

  WAIT_THREADS(i)--;
  return NULL;
}
Exemple #6
0
/* main program */ 
int main(){ 
	
	
	
	
	setlogmask(LOG_UPTO(LOG_INFO));
        openlog(PROG_NAME, LOG_PID | LOG_CONS | LOG_PERROR, LOG_USER);
        syslog(LOG_INFO, "Program started");
        /* 
        	Check if parent process id is set not to 1 (init). 
        	If it is we are already a child and we can go straight to 
        	the task of waiting for a connection 
        */
        if (getppid() !=  1)
        {
        	signal_init();
        	daemon_startup();
        }

        /*
        	We are in the child process portion of the program. 
        	The parent process should not have made it to here. 
        */
        
        int server_fd = service_startup(); 
        
        syslog(LOG_INFO, "Daemon running");
         
        while (TRUE)
        {
            
            int session_fd=accept(server_fd,0,0);
            handle_session(session_fd); 
            close(session_fd);
            
           /* sleep(1); */ 
        }
	
	
	
} 
Exemple #7
0
//--------------------------------------------------------------------------
// __try handler can't be placed in fuction which requires object unwinding
static idarpc_stream_t *protected_privileged_session(IRAPIStream* pStream)
{
  try
  {
    idarpc_stream_t *irs = init_server_irs(pStream);
    if ( irs == NULL )
      return NULL;

    rpc_server_t *server = new rpc_server_t((SOCKET)irs);
    server->verbose = verbose;
    server->set_debugger_instance(create_debug_session());

    g_global_server = server;

    handle_session(server);
    return irs;
  }
  //__except ( display_exception(GetExceptionCode(), GetExceptionInformation()) )
  catch(...)
  {
    return NULL;
  }
}
Exemple #8
0
int slice_handle(SLICE package,SESSION** data_session,STUDENT_INFO** link_student_info)
{
    SESSION *p_session = *data_session;
    int judge_return = 0;
    while(p_session!=NULL)
    {
        if (is_time_expire(p_session->first_time,package.timestamp))
        {
            handle_session(&p_session,link_student_info);
        }
        else if (p_session->id == package.session&&p_session->type == package.type&&!strcmp(p_session->mac_address,package.smac))
        {
            append_slice_to_session(&p_session,package,package.type);
            judge_return = 1;
        }
        p_session = p_session->next;
    }
    if (judge_return == 0)
    {
        create_session_and_add_slice(data_session,package,package.type);
    }
    return 0;
}
int main (int argc, char *argv[])
{
const char* hostname=0; /* wildcard */
const char* portname="daytime";
struct addrinfo hints;
memset(&hints,0,sizeof(hints));
hints.ai_family=AF_UNSPEC;
hints.ai_socktype=SOCK_STREAM;
hints.ai_protocol=0;
// [1] The AI_PASSIVE flag has been set because the address is intended for binding to a server socket. It causes the IP address to default to the wildcard address as opposed to the loopback address.
// [2] The AI_ADDRCONFIG flag has been set so that IPv6 results will only be returned if the server has an IPv6 address, and similarly for IPv4.
hints.ai_flags=AI_PASSIVE|AI_ADDRCONFIG;
struct addrinfo* res=0;
int err=getaddrinfo(hostname,portname,&hints,&res);
if (err!=0) {
    die("failed to resolve local socket address (err=%d)",err);
}
// create socket
int server_fd=socket(res->ai_family,res->ai_socktype,res->ai_protocol);
if (server_fd==-1) {
    die("%s",strerror(errno));
}
// Set the SO_REUSEADDR socket option
int reuseaddr=1;
if (setsockopt(server_fd,SOL_SOCKET,SO_REUSEADDR,&reuseaddr,sizeof(reuseaddr))==-1) {
    die("%s",strerror(errno));
}
// bind()
if (bind(server_fd,res->ai_addr,res->ai_addrlen)==-1) {
    die("%s",strerror(errno));
}
//If the local address was constructed using getaddrinfo then the memory occupied by the address list can now be released:
freeaddrinfo(res);
// (If the address list has been searched or filtered then take care that it is the head of the list that is released, not the address that you have chosen to use.)

// lsiten()
if (listen(server_fd,SOMAXCONN)) {
    die("failed to listen for connections (errno=%d)",errno);
}
// accept() and making sure each accept() is a process
// Note: The parent process should close the descriptor for each connected socket once the corresponding child process has been spawned. There are two reasons for doing this: to prevent the descriptors from accumulating, and to prevent the connection from being held open by the parent after it has been closed by the child. Similarly, the child process should close any file or socket descriptors inherited from the parent that it does not need access to. This will certainly include the descriptor for the server socket, but you should consider whether there are any others.
for (;;) {
    int session_fd=accept(server_fd,0,0);
    if (session_fd==-1) {
        if (errno==EINTR) continue;
        die("failed to accept connection (errno=%d)",errno);
    }
    pid_t pid=fork();
    if (pid==-1) {
        die("failed to create child process (errno=%d)",errno);
    } else if (pid==0) {
        close(server_fd);
        handle_session(session_fd);
        close(session_fd);
        _exit(0);
    } else {
        close(session_fd);
    }
}


}
Exemple #10
0
static void handle_session(ssh_event event, ssh_session session) {
    int n;
    int rc = 0;

    /* Structure for storing the pty size. */
    struct winsize wsize = {
        .ws_row = 0,
        .ws_col = 0,
        .ws_xpixel = 0,
        .ws_ypixel = 0
    };

    /* Our struct holding information about the channel. */
    struct channel_data_struct cdata = {
        .pid = 0,
        .pty_master = -1,
        .pty_slave = -1,
        .child_stdin = -1,
        .child_stdout = -1,
        .child_stderr = -1,
        .event = NULL,
        .winsize = &wsize
    };

    /* Our struct holding information about the session. */
    struct session_data_struct sdata = {
        .channel = NULL,
        .auth_attempts = 0,
        .authenticated = 0
    };

    struct ssh_channel_callbacks_struct channel_cb = {
        .userdata = &cdata,
        .channel_pty_request_function = pty_request,
        .channel_pty_window_change_function = pty_resize,
        .channel_shell_request_function = shell_request,
        .channel_exec_request_function = exec_request,
        .channel_data_function = data_function,
        .channel_subsystem_request_function = subsystem_request
    };

    struct ssh_server_callbacks_struct server_cb = {
        .userdata = &sdata,
        .auth_password_function = auth_password,
        .channel_open_request_session_function = channel_open,
    };

    if (authorizedkeys[0]) {
        server_cb.auth_pubkey_function = auth_publickey;
        ssh_set_auth_methods(session, SSH_AUTH_METHOD_PASSWORD | SSH_AUTH_METHOD_PUBLICKEY);
    } else
        ssh_set_auth_methods(session, SSH_AUTH_METHOD_PASSWORD);

    ssh_callbacks_init(&server_cb);
    ssh_callbacks_init(&channel_cb);

    ssh_set_server_callbacks(session, &server_cb);

    if (ssh_handle_key_exchange(session) != SSH_OK) {
        fprintf(stderr, "%s\n", ssh_get_error(session));
        return;
    }

    ssh_event_add_session(event, session);

    n = 0;
    while (sdata.authenticated == 0 || sdata.channel == NULL) {
        /* If the user has used up all attempts, or if he hasn't been able to
         * authenticate in 10 seconds (n * 100ms), disconnect. */
        if (sdata.auth_attempts >= 3 || n >= 100) {
            return;
        }

        if (ssh_event_dopoll(event, 100) == SSH_ERROR) {
            fprintf(stderr, "%s\n", ssh_get_error(session));
            return;
        }
        n++;
    }

    ssh_set_channel_callbacks(sdata.channel, &channel_cb);

    do {
        /* Poll the main event which takes care of the session, the channel and
         * even our child process's stdout/stderr (once it's started). */
        if (ssh_event_dopoll(event, -1) == SSH_ERROR) {
          ssh_channel_close(sdata.channel);
        }

        /* If child process's stdout/stderr has been registered with the event,
         * or the child process hasn't started yet, continue. */
        if (cdata.event != NULL || cdata.pid == 0) {
            continue;
        }
        /* Executed only once, once the child process starts. */
        cdata.event = event;
        /* If stdout valid, add stdout to be monitored by the poll event. */
        if (cdata.child_stdout != -1) {
            if (ssh_event_add_fd(event, cdata.child_stdout, POLLIN, process_stdout,
                                 sdata.channel) != SSH_OK) {
                fprintf(stderr, "Failed to register stdout to poll context\n");
                ssh_channel_close(sdata.channel);
            }
        }

        /* If stderr valid, add stderr to be monitored by the poll event. */
        if (cdata.child_stderr != -1){
            if (ssh_event_add_fd(event, cdata.child_stderr, POLLIN, process_stderr,
                                 sdata.channel) != SSH_OK) {
                fprintf(stderr, "Failed to register stderr to poll context\n");
                ssh_channel_close(sdata.channel);
            }
        }
    } while(ssh_channel_is_open(sdata.channel) &&
            (cdata.pid == 0 || waitpid(cdata.pid, &rc, WNOHANG) == 0));

    close(cdata.pty_master);
    close(cdata.child_stdin);
    close(cdata.child_stdout);
    close(cdata.child_stderr);

    /* Remove the descriptors from the polling context, since they are now
     * closed, they will always trigger during the poll calls. */
    ssh_event_remove_fd(event, cdata.child_stdout);
    ssh_event_remove_fd(event, cdata.child_stderr);

    /* If the child process exited. */
    if (kill(cdata.pid, 0) < 0 && WIFEXITED(rc)) {
        rc = WEXITSTATUS(rc);
        ssh_channel_request_send_exit_status(sdata.channel, rc);
    /* If client terminated the channel or the process did not exit nicely,
     * but only if something has been forked. */
    } else if (cdata.pid > 0) {
        kill(cdata.pid, SIGKILL);
    }

    ssh_channel_send_eof(sdata.channel);
    ssh_channel_close(sdata.channel);

    /* Wait up to 5 seconds for the client to terminate the session. */
    for (n = 0; n < 50 && (ssh_get_status(session) & SESSION_END) == 0; n++) {
        ssh_event_dopoll(event, 100);
    }
}

/* SIGCHLD handler for cleaning up dead children. */
static void sigchld_handler(int signo) {
    (void) signo;
    while (waitpid(-1, NULL, WNOHANG) > 0);
}

int main(int argc, char **argv) {
    ssh_bind sshbind;
    ssh_session session;
    ssh_event event;
    struct sigaction sa;
    int rc;

    /* Set up SIGCHLD handler. */
    sa.sa_handler = sigchld_handler;
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = SA_RESTART | SA_NOCLDSTOP;
    if (sigaction(SIGCHLD, &sa, NULL) != 0) {
        fprintf(stderr, "Failed to register SIGCHLD handler\n");
        return 1;
    }

    rc = ssh_init();
    if (rc < 0) {
        fprintf(stderr, "ssh_init failed\n");
        return 1;
    }

    sshbind = ssh_bind_new();
    if (sshbind == NULL) {
        fprintf(stderr, "ssh_bind_new failed\n");
        return 1;
    }

#ifdef HAVE_ARGP_H
    argp_parse(&argp, argc, argv, 0, 0, sshbind);
#else
    (void) argc;
    (void) argv;

    set_default_keys(sshbind, 0, 0, 0);
#endif /* HAVE_ARGP_H */

    if(ssh_bind_listen(sshbind) < 0) {
        fprintf(stderr, "%s\n", ssh_get_error(sshbind));
        return 1;
    }

    while (1) {
        session = ssh_new();
        if (session == NULL) {
            fprintf(stderr, "Failed to allocate session\n");
            continue;
        }

        /* Blocks until there is a new incoming connection. */
        if(ssh_bind_accept(sshbind, session) != SSH_ERROR) {
            switch(fork()) {
                case 0:
                    /* Remove the SIGCHLD handler inherited from parent. */
                    sa.sa_handler = SIG_DFL;
                    sigaction(SIGCHLD, &sa, NULL);
                    /* Remove socket binding, which allows us to restart the
                     * parent process, without terminating existing sessions. */
                    ssh_bind_free(sshbind);

                    event = ssh_event_new();
                    if (event != NULL) {
                        /* Blocks until the SSH session ends by either
                         * child process exiting, or client disconnecting. */
                        handle_session(event, session);
                        ssh_event_free(event);
                    } else {
                        fprintf(stderr, "Could not create polling context\n");
                    }
                    ssh_disconnect(session);
                    ssh_free(session);

                    exit(0);
                case -1:
                    fprintf(stderr, "Failed to fork\n");
            }
        } else {
            fprintf(stderr, "%s\n", ssh_get_error(sshbind));
        }
        /* Since the session has been passed to a child fork, do some cleaning
         * up at the parent process. */
        ssh_disconnect(session);
        ssh_free(session);
    }

    ssh_bind_free(sshbind);
    ssh_finalize();
    return 0;
}
Exemple #11
0
//--------------------------------------------------------------------------
// debugger remote server - TCP/IP mode
int NT_CDECL main(int argc, char *argv[])
{
  int port_number = DEBUGGER_PORT_NUMBER;
  lprintf("IDA " SYSTEM SYSBITS " remote debug server(" __SERVER_TYPE__ ") v1.%d. Copyright HexRays 2004-2010\n", IDD_INTERFACE_VERSION);
  while ( argc > 1 && (argv[1][0] == '-' || argv[1][0] == '/'))
  {
    switch ( argv[1][1] )
    {
    case 'p':
      port_number = atoi(&argv[1][2]);
      break;
    case 'P':
      server_password = argv[1] + 2;
      break;
    case 'v':
      verbose = true;
      break;
    default:
      error("usage: ida_remote [switches]\n"
        "  -p...  port number\n"
        "  -P...  password\n"
        "  -v     verbose\n");
    }
    argv++;
    argc--;
  }

  // call the debugger module to initialize its subsystem once
  if (
    !init_subsystem()
#ifndef __SINGLE_THREADED_SERVER__
    || ((g_lock = qmutex_create())== NULL)
#endif
    )
  {
    lprintf("Could not initialize subsystem!");
    return -1;
  }

#ifndef __NT__
  signal(SIGHUP, shutdown_gracefully);
#endif
  signal(SIGINT, shutdown_gracefully);
  signal(SIGTERM, shutdown_gracefully);
  signal(SIGSEGV, shutdown_gracefully);
  //  signal(SIGPIPE, SIG_IGN);

  if ( !init_irs_layer() )
  {
    neterr(NULL, "init_sockets");
  }

  listen_socket = socket(AF_INET, SOCK_STREAM, 0);

  if ( listen_socket == -1 )
    neterr(NULL, "socket");

  setup_irs((idarpc_stream_t*)listen_socket);

  struct sockaddr_in sa;
  memset(&sa, 0, sizeof(sa));
  sa.sin_family = AF_INET;
  sa.sin_port   = qhtons(short(port_number));

  if ( bind(listen_socket, (sockaddr *)&sa, sizeof(sa)) == SOCKET_ERROR )
    neterr((idarpc_stream_t *)listen_socket, "bind");

  if ( listen(listen_socket, SOMAXCONN) == SOCKET_ERROR )
    neterr((idarpc_stream_t *)listen_socket, "listen");

  hostent *local_host = gethostbyname("");
  if ( local_host != NULL )
  {
    const char *local_ip = inet_ntoa (*(struct in_addr *)*local_host->h_addr_list);
    if ( local_host->h_name != NULL && local_ip != NULL )
      lprintf("Host %s (%s): ", local_host->h_name, local_ip);
    else if ( local_ip != NULL )
      lprintf("Host %s: ", local_ip);
  }
  lprintf("Listening on port #%u...\n", port_number);

  while ( true )
  {
    sockaddr_in sa;
    socklen_t salen = sizeof(sa);
    SOCKET rpc_socket = accept(listen_socket, (sockaddr *)&sa, &salen);
    if ( rpc_socket == -1 )
      neterr((idarpc_stream_t *)listen_socket, "accept");
#if defined(__LINUX__) && defined(LIBWRAP)
    const char *p;
    if ( (p=check_connection(rpc_socket)) != NULL )
    {
      fprintf(stderr,
        "ida-server CONNECTION REFUSED from %s (tcp_wrappers)\n", p);
      shutdown(rpc_socket, 2);
      close(rpc_socket);
      continue;
    }
#endif // defined(__LINUX__) && defined(LIBWRAP)

    rpc_server_t *server = new rpc_server_t(rpc_socket);
    server->verbose = verbose;
    server->set_debugger_instance(create_debug_session());
    handle_session(server);
  }
/* NOTREACHED
  term_subsystem();
#ifndef __SINGLE_THREADED_SERVER__
  qmutex_free(g_lock);
#endif
*/
}
Exemple #12
0
//--------------------------------------------------------------------------
// debugger remote server - TCP/IP mode
int NT_CDECL main(int argc, char *argv[])
{
#ifdef ENABLE_LOWCNDS
  init_idc();
#endif

  // call the debugger module to initialize its subsystem once
  if ( !init_lock()
    || !init_subsystem()
#ifndef __SINGLE_THREADED_SERVER__
    || !srv_lock_init()
#endif
    )
  {
    lprintf("Could not initialize subsystem!");
    return -1;
  }

  bool reuse_conns = are_broken_connections_supported();
  int port_number = DEBUGGER_PORT_NUMBER;
  lprintf("IDA " SYSTEM SYSBITS " remote debug server(" __SERVER_TYPE__ ") v1.%d. Hex-Rays (c) 2004-2014\n", IDD_INTERFACE_VERSION);
  while ( argc > 1 && (argv[1][0] == '-' || argv[1][0] == '/'))
  {
    switch ( argv[1][1] )
    {
    case 'p':
      port_number = atoi(&argv[1][2]);
      break;
    case 'P':
      server_password = argv[1] + 2;
      break;
    case 'i':
      ipv4_address = argv[1] + 2;
      break;
    case 'v':
      verbose = true;
      break;
    case 'k':
      if ( !reuse_conns )
        error("Sorry, debugger doesn't support reusing broken connections\n");
      keep_broken_connections = true;
      break;
    default:
      error("usage: ida_remote [switches]\n"
               "  -i...  IP address to bind to (default to any)\n"
               "  -v     verbose\n"
               "  -p...  port number\n"
               "  -P...  password\n"
               "%s", reuse_conns ? "  -k     keep broken connections\n" : "");
      break;
    }
    argv++;
    argc--;
  }

#ifndef UNDER_CE
#ifndef __NT__
  signal(SIGHUP, shutdown_gracefully);
#endif
  signal(SIGINT, shutdown_gracefully);
  signal(SIGTERM, shutdown_gracefully);
  signal(SIGSEGV, shutdown_gracefully);
  //  signal(SIGPIPE, SIG_IGN);
#endif

  if ( !init_irs_layer() )
  {
    neterr(NULL, "init_sockets");
  }

  listen_socket = socket(AF_INET, SOCK_STREAM, 0);
  if ( listen_socket == INVALID_SOCKET )
    neterr(NULL, "socket");

  idarpc_stream_t *irs = (idarpc_stream_t *)listen_socket;
  setup_irs(irs);

  struct sockaddr_in sa;
  memset(&sa, 0, sizeof(sa));
  sa.sin_family = AF_INET;
  sa.sin_port   = qhtons(short(port_number));
  if ( ipv4_address != NULL )
    sa.sin_addr.s_addr = inet_addr(ipv4_address);
  if( sa.sin_addr.s_addr == INADDR_NONE )
  {
    lprintf("Cannot parse IP v4 address %s, falling back to INADDR_ANY\n", ipv4_address);
    sa.sin_addr.s_addr = INADDR_ANY;
    ipv4_address = NULL;
  }

  if ( bind(listen_socket, (sockaddr *)&sa, sizeof(sa)) == SOCKET_ERROR )
    neterr(irs, "bind");

  if ( listen(listen_socket, SOMAXCONN) == SOCKET_ERROR )
    neterr(irs, "listen");

  hostent *local_host = gethostbyname("");
  if ( local_host != NULL )
  {
    const char *local_ip;
    if ( ipv4_address != NULL )
      local_ip = ipv4_address;
    else
      local_ip = inet_ntoa(*(struct in_addr *)*local_host->h_addr_list);
    if ( local_host->h_name != NULL && local_ip != NULL )
      lprintf("Host %s (%s): ", local_host->h_name, local_ip);
    else if ( local_ip != NULL )
      lprintf("Host %s: ", local_ip);
  }
  lprintf("Listening on port #%u...\n", port_number);

  while ( true )
  {
    socklen_t salen = sizeof(sa);
    SOCKET rpc_socket = accept(listen_socket, (sockaddr *)&sa, &salen);
    if ( rpc_socket == INVALID_SOCKET )
    {
#ifdef UNDER_CE
      if ( WSAGetLastError() != WSAEINTR )
#else
      if ( errno != EINTR )
#endif
        neterr(irs, "accept");
      continue;
    }
#if defined(__LINUX__) && defined(LIBWRAP)
    const char *p = check_connection(rpc_socket);
    if ( p != NULL )
    {
      fprintf(stderr,
        "ida-server CONNECTION REFUSED from %s (tcp_wrappers)\n", p);
      shutdown(rpc_socket, 2);
      close(rpc_socket);
      continue;
    }
#endif // defined(__LINUX__) && defined(LIBWRAP)

    rpc_server_t *server = new rpc_server_t((idarpc_stream_t *)rpc_socket);
    server->verbose = verbose;
    server->set_debugger_instance(create_debug_session());
    {
#ifdef UNDER_CE
      get_permissions_t all_permissions;
#endif
      handle_session(server);
    }
  }
/* NOTREACHED
  term_lock();
  term_subsystem();
#ifndef __SINGLE_THREADED_SERVER__
  qmutex_free(g_lock);
#endif
*/
}