Example #1
0
static void* connection_handler(void* data)
{
	socket_info_t* socket_info = (socket_info_t*)data;
	thread_t ctod;

	debug("%s: client_fd = %d\n", __func__, socket_info->client_fd);

	/* spawn client to device thread */
	socket_info->stop_ctod = 0;
	if (thread_create(&ctod, thread_client_to_device, data) != 0) {
		fprintf(stderr, "Failed to start client to device thread...\n");
	}

	/* join the fun */
	thread_join(ctod);

	/* shutdown client socket */
	socket_shutdown(socket_info->client_fd, SHUT_RDWR);
	socket_close(socket_info->client_fd);

	/* shutdown server socket if we have to terminate to unblock the server loop */
	if (quit_flag) {
		socket_shutdown(socket_info->server_fd, SHUT_RDWR);
		socket_close(socket_info->server_fd);
	}

	return NULL;
}
Example #2
0
/** Terminate sources.
 *
 * Close listening Sockets and shutdown() others
 *
 * XXX: This function is not very efficient (going through the linked list of
 * channels and repeatedly calling functions which do the same), but it's only
 * used for cleanup, so it should be fine.
 *
 * \see eventloop_stop
 */
static void terminate_fds(void)
{
  Channel *ch = self.channels, *next;

  while (ch != NULL) {
    next = ch->next;
    o_log(O_LOG_DEBUG4, "EventLoop: Terminating channel %s\n", ch->name);
    if (!ch->is_active ||
        socket_is_disconnected(ch->socket) ||
        socket_is_listening(ch->socket)) {
      o_log(O_LOG_DEBUG3, "EventLoop: Releasing listening channel %s\n", ch->name);
      eventloop_socket_release((SockEvtSource*)ch);
    } else if (self.force_stop) {
      o_log(O_LOG_DEBUG3, "EventLoop: Closing down %s\n", ch->name);
      eventloop_socket_release((SockEvtSource*)ch);
      socket_close(ch->socket);
    } else {
      o_log(O_LOG_DEBUG3, "EventLoop: Shutting down %s\n", ch->name);
      socket_shutdown(ch->socket);
      ch->is_shutting_down = 1;
    }
    ch = next;
  }

  update_fds();
}
Example #3
0
/* UNIX local-domain socket module invocation ********************************/
unsigned cvm_xfer_local_packets(const char* path,
				const struct cvm_packet* request,
				struct cvm_packet* response)
{
  int sock;
  int result;
  unsigned io;
  unsigned done;
  unsigned len;
  result = CVME_IO;
  response->length = 0;
  if ((sock = socket_unixstr()) != -1 &&
      socket_connectu(sock, path)) {
    for (done = 0, len = request->length; done < len; done += io) {
      if ((io = write(sock, request->data+done, len-done)) == 0) break;
      if (io == (unsigned)-1) break;
    }
    socket_shutdown(sock, 0, 1);
    if (done >= len) {
      for (done = 0; done < CVM_BUFSIZE; done += io) {
	if ((io = read(sock, response->data+done, CVM_BUFSIZE-done)) == 0)
	  break;
	if (io == (unsigned)-1) done = CVM_BUFSIZE+1;
      }
      if (done <= CVM_BUFSIZE) {
	response->length = done;
	result = 0;
      }
    }
  }
  close(sock);
  return result;
}
Example #4
0
static int STDCALL http_server_thread(void* param)
{
	char req[1024] = {0};
	bool* running = (bool*)param;
	socket_t socket = tcpserver_create(NULL, PORT, 32);

	while(*running)
	{
		int r = socket_select_read(socket, 1000);
		if(1 == r)
		{
			struct sockaddr_in in4;
			socklen_t len = sizeof(in4);
			socket_t client = socket_accept(socket, (sockaddr*)&in4, &len);
			if(client != socket_invalid)
			{
				r = socket_recv_by_time(client, req, sizeof(req), 0, 5000);
				r = socket_send_all_by_time(client, s_reply, strlen(s_reply), 0, 5000);
				r = socket_shutdown(client, SHUT_RDWR);
				r = socket_close(client);
				printf("server side close socket\n");
			}
		}
	}

	return 0;
}
Example #5
0
// socket-shutdown
scm_obj_t
subr_socket_shutdown(VM* vm, int argc, scm_obj_t argv[])
{
    if (argc == 2) {
        if (SOCKETP(argv[0])) {
            if (FIXNUMP(argv[1])) {
                intptr_t how = FIXNUM(argv[1]);
                if (how >= 0 && how <= 2) {
                    try {
                        socket_shutdown((scm_socket_t)argv[0], FIXNUM(argv[1]));
                        return scm_unspecified;
                    } catch (io_exception_t& e) {
                        raise_io_error(vm, "socket-shutdown", e.m_operation, e.m_message, e.m_err, argv[0], scm_false);
                        return scm_undef;
                    }
                }
            }
            wrong_type_argument_violation(vm, "socket-shutdown", 1, "0, 1, or 2", argv[1], argc, argv);
            return scm_undef;
        }
        wrong_type_argument_violation(vm, "socket-shutdown", 0, "socket", argv[0], argc, argv);
        return scm_undef;
    }
    wrong_number_of_arguments_violation(vm, "socket-shutdown", 2, 2, argc, argv);
    return scm_undef;
}
Example #6
0
void JNL_Connection::close(int quick)
{
  if (quick || m_state == STATE_RESOLVING || m_state == STATE_CONNECTING)
  {
    m_state=STATE_CLOSED;
	/*
	**  Joshua Teitelbaum 1/27/2006
	**  virualization for ssl
	*/
	socket_shutdown();

    m_socket=-1;
    memset(m_recv_buffer,0,m_recv_buffer_len);
    memset(m_send_buffer,0,m_send_buffer_len);
    m_remote_port=0;
    m_recv_len=m_recv_pos=0;
    m_send_len=m_send_pos=0;
    m_host[0]=0;
    memset(m_saddr,0,sizeof(m_saddr));
  }
  else
  {
    if (m_state == STATE_CONNECTED) m_state=STATE_CLOSING;
  }
}
Example #7
0
/*
** err = sock.shutdown(fd, shut=sock.SHUT_RDWR)
*/
static int lsocket_shutdown(lua_State *L) 
{
	int fd = luaL_checkint(L, 1);
	int how = luaL_optint(L, 2, SHUT_RDWR);
	int err = socket_shutdown(fd, how);
	lua_pushinteger(L, err);
	return 1;
}
Example #8
0
/*-------------------------------------------------------------------------*\
* Shuts the connection down partially
\*-------------------------------------------------------------------------*/
static int meth_shutdown(lua_State *L)
{
    /* SHUT_RD,  SHUT_WR,  SHUT_RDWR  have  the value 0, 1, 2, so we can use method index directly */
    static const char* methods[] = { "receive", "send", "both", NULL };
    p_tcp tcp = (p_tcp) auxiliar_checkclass(L, "tcp{client}", 1);
    int how = luaL_checkoption(L, 2, "both", methods);
    socket_shutdown(&tcp->sock, how);
    lua_pushnumber(L, 1);
    return 1;
}
Example #9
0
static void *thread_device_to_client(void *data)
{
	socket_info_t* socket_info = (socket_info_t*)data;
	idevice_error_t res = IDEVICE_E_UNKNOWN_ERROR;

	int recv_len;
	int sent;
	char buffer[131072];

	debug("%s: started thread...\n", __func__);

	debug("%s: client_fd = %d\n", __func__, socket_info->client_fd);
	debug("%s: server fd = %d\n", __func__, socket_info->server_fd);

	while (!quit_flag && !socket_info->stop_dtoc && socket_info->client_fd > 0 && socket_info->server_fd > 0) {
		debug("%s: receiving data from device...\n", __func__);

		res = idevice_connection_receive_timeout(socket_info->device_connection, buffer, sizeof(buffer), (uint32_t*)&recv_len, 5000);

		if (recv_len <= 0) {
			if (recv_len == 0 && res == IDEVICE_E_SUCCESS) {
				// try again
				continue;
			} else {
				fprintf(stderr, "recv failed: %s\n", strerror(errno));
				break;
			}
		} else {
			/* send to device */
			debug("%s: sending data to client...\n", __func__);
			sent = socket_send(socket_info->client_fd, buffer, recv_len);
			if (sent < recv_len) {
				if (sent <= 0) {
					fprintf(stderr, "send failed: %s\n", strerror(errno));
					break;
				} else {
					fprintf(stderr, "only sent %d from %d bytes\n", sent, recv_len);
				}
			} else {
				// sending succeeded, receive from device
				debug("%s: pushed %d bytes to client\n", __func__, sent);
			}
		}
	}

	debug("%s: shutting down...\n", __func__);

	socket_shutdown(socket_info->client_fd, SHUT_RDWR);
	socket_close(socket_info->client_fd);

	socket_info->client_fd = -1;
	socket_info->stop_ctod = 1;

	return NULL;
}
Example #10
0
void ExitClient(int errcode)
{
	if (socket_shutdown(mypid) == -1)
		printf("PANIC: unable to shutdown socket\n");
	unlink(cpath);
	fflush(stdout);
	fflush(stdin);

	if (pbuff)
		free(pbuff);

	exit(errcode);
}
Example #11
0
int
ksocket_shutdown(ksocket_t ks, int how, struct cred *cr)
{
	struct sonode *so;

	/* All Solaris components should pass a cred for this operation. */
	ASSERT(cr != NULL);

	if (!KSOCKET_VALID(ks))
		return (ENOTSOCK);

	so = KSTOSO(ks);

	return (socket_shutdown(so, how, cr));
}
Example #12
0
/*-------------------------------------------------------------------------*\
* Shuts the connection down partially
\*-------------------------------------------------------------------------*/
static int meth_shutdown(lua_State *L)
{
    p_tcp tcp = (p_tcp) auxiliar_checkclass(L, "tcp{client}", 1);
    const char *how = luaL_optstring(L, 2, "both");
    switch (how[0]) {
        case 'b':
            if (strcmp(how, "both")) goto error;
            socket_shutdown(&tcp->sock, 2);
            break;
        case 's':
            if (strcmp(how, "send")) goto error;
            socket_shutdown(&tcp->sock, 1);
            break;
        case 'r':
            if (strcmp(how, "receive")) goto error;
            socket_shutdown(&tcp->sock, 0);
            break;
    }
    lua_pushnumber(L, 1);
    return 1;
error:
    luaL_argerror(L, 2, "invalid shutdown method");
    return 0;
}
Example #13
0
void gwlib_shutdown(void) 
{
    gwlib_assert_init();
    charset_shutdown();
    http_shutdown();
    socket_shutdown();
    gwthread_shutdown();
    octstr_shutdown();
    gwlib_protected_shutdown();
    uuid_shutdown();
    cfg_shutdown();
    gw_check_leaks();
    log_shutdown();
    gwmem_shutdown();
    init = 0;
}
Example #14
0
JNL_Connection::~JNL_Connection()
{
  /*
  **  Joshua Teitelbaum 1/27/2006
  **  virtualization for ssl, calling socket_shtudown()
  */
  socket_shutdown();

  free(m_recv_buffer);
  free(m_send_buffer);
  if (m_dns_owned) 
  {
    delete m_dns;
  }
  delete m_saddr;
}
Example #15
0
int main()
{
	if (!socket_init())
		return -1;

	ncurses_init();

	ncurses_print("Welcome to the bedrock console.\n");
	ncurses_print("To exit type \"quit\"\n");

	while (console_running)
		socket_process();

	ncurses_shutdown();
	socket_shutdown();

	return 0;
}
Example #16
0
int zsp_listener_stop(zsp_listener_t *listener)
{
	if (listener == NULL)
		return SSS_ERROR;

	if (listener->sock != NULL)
	{
		socket_shutdown(listener->sock);
		socket_delete(listener->sock);
		listener->sock = NULL;
	}
	if (listener->thread != NULL)
	{
		thread_stop(listener->thread);
		thread_delete(listener->thread);
		listener->thread = NULL;
	}
	listener->port = 0;

	return SSS_OK;
}
Example #17
0
File: bye.c Project: ftnapps/FTNd
void Quick_Bye(int onsig)
{
    char    *temp;
    int	    i;

    temp = calloc(PATH_MAX, sizeof(char));
    Syslog('+', "Quick_Bye");
    socket_shutdown(mypid);
    snprintf(temp, PATH_MAX, "%s/tmp/ftnd%d", getenv("FTND_ROOT"), getpid());
    unlink(temp);
    free(temp);
    colour(LIGHTGRAY, BLACK);
    sleep(3);

    if ((onsig != SIGALRM) && (onsig != FTNERR_TIMEOUT) && (hanged_up == 0)) {
        cookedport();
    }

    /*
     * Ignore SIGHUP during hangup
     */
    signal(SIGHUP, SIG_IGN);
    hangup();

    /*
     * Prevent that we call die() if something goes wrong next
     */
    for (i = 0; i < NSIG; i++)
        if ((i == SIGHUP) || (i == SIGPIPE) || (i == SIGBUS) || (i == SIGILL) || (i == SIGSEGV) || (i == SIGTERM))
            signal(i, SIG_DFL);

    free(pTTY);
    if (StartTime)
	free(StartTime);
    exit(FTNERR_OK);
}
Example #18
0
/*
 * Main routine.  Parse the arguments, open the remctl connection, send the
 * command, and then call process_response.
 */
int
main(int argc, char *argv[])
{
    int option, status;
    char *server_host;
    struct addrinfo hints, *ai;
    const char *source = NULL;
    const char *service_name = NULL;
    unsigned short port = 0;
    struct remctl *r;
    int errorcode = 0;

    /* Set up logging and identity. */
    message_program_name = "remctl";
    if (!socket_init())
        die("failed to initialize socket library");

    /*
     * Parse options.  The + tells GNU getopt to stop option parsing at the
     * first non-argument rather than proceeding on to find options anywhere.
     * Without this, it's hard to call remote programs that take options.
     * Non-GNU getopt will treat the + as a supported option, which is handled
     * below.
     */
    while ((option = getopt(argc, argv, "+b:dhp:s:v")) != EOF) {
        switch (option) {
        case 'b':
            source = optarg;
            break;
        case 'd':
            message_handlers_debug(1, message_log_stderr);
            break;
        case 'h':
            usage(0);
            break;
        case 'p':
            port = atoi(optarg);
            break;
        case 's':
            service_name = optarg;
            break;
        case 'v':
            printf("%s\n", PACKAGE_STRING);
            exit(0);
            break;
        case '+':
            fprintf(stderr, "%s: invalid option -- +\n", argv[0]);
        default:
            usage(1);
            break;
        }
    }
    argc -= optind;
    argv += optind;
    if (argc < 2)
        usage(1);
    server_host = *argv++;
    argc--;

    /*
     * If service_name isn't set, the remctl library uses host/<server>
     * (host@<server> in GSS-API parlance).  However, if the server to which
     * we're connecting is a DNS-load-balanced name, we have to be careful
     * what principal name we use.
     *
     * Ideally, we would let the GSS-API library handle this and choose
     * whether to canonicalize the <server> in the principal name based on the
     * krb5.conf rdns setting and similar configuration.  However, with DNS
     * load balancing, this still may fail.  At the time of network
     * connection, we will connect to whatever the name resolves to then.
     * After we connect, we authenticate, and the GSS-API library will then
     * separately canonicalize the hostname.  It could get a different answer
     * than we got for our network connection, leading to an authentication
     * failure.
     *
     * Therefore, if the principal isn't specified, we canonicalize the
     * hostname to which we're connecting before we connect.  Then, the
     * additional canonicalization possibly done by the GSS-API library should
     * return the same results and be consistent.
     *
     * Note that this opens the possibility of a subtle attack through DNS
     * spoofing, since both the principal used and the host to which we're
     * connecting can be changed by varying the DNS response.
     *
     * If the principal is specified explicitly, assume the user knows what
     * they're doing and don't do any of this.
     */
    if (service_name == NULL) {
        memset(&hints, 0, sizeof(hints));
        hints.ai_flags = AI_CANONNAME;
        status = getaddrinfo(server_host, NULL, &hints, &ai);
        if (status != 0)
            die("cannot resolve host %s: %s", server_host,
                gai_strerror(status));
        server_host = xstrdup(ai->ai_canonname);
        freeaddrinfo(ai);
    }

    /* Open connection. */
    r = remctl_new();
    if (r == NULL)
        sysdie("cannot initialize remctl connection");
    if (source != NULL)
        if (!remctl_set_source_ip(r, source))
            die("%s", remctl_error(r));
    if (!remctl_open(r, server_host, port, service_name))
        die("%s", remctl_error(r));

    /* Do the work. */
    if (!remctl_command(r, (const char **) argv))
        die("%s", remctl_error(r));
    if (!process_response(r, &errorcode))
        die("%s", remctl_error(r));

    /* Shut down cleanly. */
    remctl_close(r);
    socket_shutdown();
    return errorcode;
}
Example #19
0
File: bye.c Project: ftnapps/FTNd
void Good_Bye(int onsig)
{
    FILE    *pUsrConfig, *pExitinfo;
    char    *temp;
    int	    offset;
    time_t  t_end;
    int	    i;

    IsDoing("Hangup");
    temp = calloc(PATH_MAX, sizeof(char));
    Syslog('+', "Good_Bye(%d)", onsig);

    /*
     * Don't display goodbye screen on SIGHUP and idle timeout.
     * With idle timeout this will go into a loop.
     */
    if ((onsig != SIGALRM) && (onsig != FTNERR_TIMEOUT) && (hanged_up == 0))
	DisplayFile((char *)"goodbye");

    SaveLastCallers();

    /*
     * Update the users database record.
     */
    snprintf(temp, PATH_MAX, "%s/etc/users.data", getenv("FTND_ROOT"));
    if ((pUsrConfig = fopen(temp,"r+")) != NULL) {
	snprintf(temp, PATH_MAX, "%s/%s/exitinfo", CFG.bbs_usersdir, exitinfo.Name);
	if ((pExitinfo = fopen(temp,"rb")) != NULL) {
	    fread(&usrconfighdr, sizeof(usrconfighdr), 1, pUsrConfig);
	    fread(&exitinfo, sizeof(exitinfo), 1, pExitinfo);

	    usrconfig = exitinfo;
	    fclose(pExitinfo);
	    usrconfig.iLastFileArea = iAreaNumber;

	    /* If time expired, do not say say successful logoff */
	    if (!iExpired && !hanged_up)
		Syslog('+', "User successfully logged off BBS");

	    usrconfig.iLastMsgArea = iMsgAreaNumber;

	    offset = usrconfighdr.hdrsize + (grecno * usrconfighdr.recsize);
	    if (fseek(pUsrConfig, offset, SEEK_SET) != 0) {
		WriteError("$Can't move pointer in file %s/etc/users.data", getenv("FTND_ROOT"));
	    } else {
	        fwrite(&usrconfig, sizeof(usrconfig), 1, pUsrConfig);
	    }
	    fclose(pUsrConfig);
	}
    }

    /*
     * Update mib counters
     */
    t_end = time(NULL);
    mib_minutes = (unsigned int) ((t_end - t_start) / 60);
    mib_sessions++;

    sendmibs();

    /*
     * Flush all data to the user, wait 5 seconds to
     * be sure the user received all data.
     */
    if ((onsig != SIGALRM) && (onsig != FTNERR_TIMEOUT) && (hanged_up == 0)) {
	colour(LIGHTGRAY, BLACK);
	sleep(4);
    }

    for (i = 0; i < NSIG; i++) {
	if (i == SIGCHLD)
	    signal(i, SIG_DFL);
	else if ((i != SIGKILL) && (i != SIGSTOP))
	    signal(i, SIG_DFL);
    }

    if ((onsig != SIGALRM) && (onsig != FTNERR_TIMEOUT) && (hanged_up == 0)) {
    	cookedport();
    }

    /*
     * Ignore SIGHUP during hangup.
     */
    signal(SIGHUP, SIG_IGN);
    hangup();

    for (i = 0; i < NSIG; i++) {
	if ((i == SIGHUP) || (i == SIGPIPE) || (i == SIGBUS) || (i == SIGILL) || (i == SIGSEGV) || (i == SIGTERM))
	    signal(i, SIG_DFL);
    }
    
    if (do_mailout)
	CreateSema((char *)"mailout");

    t_end = time(NULL);
    Syslog(' ', "FTNDBBS finished in %s", t_elapsed(t_start, t_end));
    sleep(1);

    /*
     * Start shutting down this session, cleanup some files.
     */
    socket_shutdown(mypid);
    snprintf(temp, PATH_MAX, "%s/tmp/ftnd%d", getenv("FTND_ROOT"), getpid());
    unlink(temp);

    snprintf(temp, PATH_MAX, "%s/%s/.quote", CFG.bbs_usersdir, exitinfo.Name);
    unlink(temp);

    snprintf(temp, PATH_MAX, "%s/%s/data.msg", CFG.bbs_usersdir, exitinfo.Name);
    unlink(temp);

    snprintf(temp, PATH_MAX, "%s/%s/door.sys", CFG.bbs_usersdir, exitinfo.Name);
    unlink(temp);

    snprintf(temp, PATH_MAX, "%s/%s/door32.sys", CFG.bbs_usersdir, exitinfo.Name);
    unlink(temp);

    snprintf(temp, PATH_MAX, "%s/%s/exitinfo", CFG.bbs_usersdir, exitinfo.Name);
    unlink(temp);
    free(temp);
    unlink("taglist");

    Free_Language();
    free(pTTY);
    if (StartTime)
	free(StartTime);
    deinitnl();
    exit(onsig);
}
Example #20
0
int main(int argc, char *argv[])
{
	lockdownd_client_t lockdown = NULL;
	idevice_t device = NULL;
	idevice_connection_t connection = NULL;
	idevice_error_t ret = IDEVICE_E_UNKNOWN_ERROR;
	thread_t th;
	const char* udid = NULL;
	lockdownd_service_descriptor_t service = NULL;
	uint16_t local_port = 0;
	int result = EXIT_SUCCESS;
	int i;

	/* bind signals */
	signal(SIGINT, clean_exit);
	signal(SIGTERM, clean_exit);
#ifndef WIN32
	signal(SIGQUIT, clean_exit);
	signal(SIGPIPE, SIG_IGN);
#endif

	/* parse cmdline arguments */
	for (i = 1; i < argc; i++) {
		if (!strcmp(argv[i], "-d") || !strcmp(argv[i], "--debug")) {
			debug_mode = 1;
			idevice_set_debug_level(1);
			socket_set_verbose(3);
			continue;
		}
		else if (!strcmp(argv[i], "-u") || !strcmp(argv[i], "--udid")) {
			i++;
			if (!argv[i] || (strlen(argv[i]) != 40)) {
				print_usage(argc, argv);
				return 0;
			}
			udid = argv[i];
			continue;
		}
		else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) {
			print_usage(argc, argv);
			return EXIT_SUCCESS;
		}
		else if (atoi(argv[i]) > 0) {
			local_port = atoi(argv[i]);
			continue;
		}
		else {
			print_usage(argc, argv);
			return EXIT_SUCCESS;
		}
	}

	/* a PORT is mandatory */
	if (!local_port) {
		fprintf(stderr, "Please specify a PORT.\n");
		print_usage(argc, argv);
		goto leave_cleanup;
	}

	/* start services and connect to device */
	ret = idevice_new(&device, udid);
	if (ret != IDEVICE_E_SUCCESS) {
		if (udid) {
			fprintf(stderr, "No device found with udid %s, is it plugged in?\n", udid);
		} else {
			fprintf(stderr, "No device found, is it plugged in?\n");
		}
		result = EXIT_FAILURE;
		goto leave_cleanup;
	}

	if (LOCKDOWN_E_SUCCESS != lockdownd_client_new_with_handshake(device, &lockdown, "idevicedebugserverproxy")) {
		fprintf(stderr, "Could not connect to lockdownd. Exiting.\n");
		result = EXIT_FAILURE;
		goto leave_cleanup;
	}

	if ((lockdownd_start_service(lockdown, "com.apple.debugserver", &service) != LOCKDOWN_E_SUCCESS) || !service || !service->port) {
		fprintf(stderr, "Could not start com.apple.debugserver!\nPlease make sure to mount the developer disk image first.\n");
		result = EXIT_FAILURE;
		goto leave_cleanup;
	}

	if (idevice_connect(device, service->port, &connection) != IDEVICE_E_SUCCESS) {
		fprintf(stderr, "Connection to debugserver port %d failed!\n", (int)service->port);
		result = EXIT_FAILURE;
		goto leave_cleanup;
	}

	/* free lockdown connection if running as it is not needed anymore */
	if (lockdown) {
		lockdownd_client_free(lockdown);
		lockdown = NULL;
	}

	/* setup and create socket endpoint */
	socket_info_t socket_info;

	socket_info.device_connection = connection;
	socket_info.local_port = local_port;
	socket_info.remote_port = service->port;

	if (service) {
		lockdownd_service_descriptor_free(service);
		service = NULL;
	}

	/* create local socket */
	socket_info.server_fd = socket_create(socket_info.local_port);
	if (socket_info.server_fd < 0) {
		fprintf(stderr, "Could not create socket\n");
		result = EXIT_FAILURE;
		goto leave_cleanup;
	}

	while (!quit_flag) {
		debug("%s: Waiting for connection on local port %d\n", __func__, socket_info.local_port);

		/* wait for client */
		socket_info.client_fd = socket_accept(socket_info.server_fd, socket_info.local_port);
		if (socket_info.client_fd < 0) {
			debug("%s: Continuing...\n", __func__);
			continue;
		}

		debug("%s: Handling new client connection...\n", __func__);

		if (thread_create(&th, connection_handler, (void*)&socket_info) != 0) {
			fprintf(stderr, "Could not start connection handler.\n");
			socket_shutdown(socket_info.server_fd, SHUT_RDWR);
			socket_close(socket_info.server_fd);
		}
	}

	debug("%s: Shutting down debugserver proxy...\n", __func__);

leave_cleanup:
	if (connection) {
		idevice_disconnect(connection);
	}
	if (lockdown) {
		lockdownd_client_free(lockdown);
	}
	if (device) {
		idevice_free(device);
	}

	return result;
}
Example #21
0
URL url_http_open(char *name)
{
    URL_http *url;
    SOCKET fd;
    char *host, *path = NULL, *p;
    unsigned short port;
    char buff[BUFSIZ];
    char wwwserver[256];
    int n;

#ifdef DEBUG
    printf("url_http_open(%s)\n", name);
#endif /* DEBUG */

    url = (URL_http *)alloc_url(sizeof(URL_http));
    if(url == NULL)
    {
	url_errno = errno;
	return NULL;
    }

    /* common members */
    URLm(url, type)      = URL_http_t;
    URLm(url, url_read)  = url_http_read;
    URLm(url, url_gets)  = url_http_gets;
    URLm(url, url_fgetc) = url_http_fgetc;
    URLm(url, url_seek)  = NULL;
    URLm(url, url_tell)  = NULL;
    URLm(url, url_close) = url_http_close;

    /* private members */
    url->fp = NULL;

    if(url_http_proxy_host)
    {
	char *q;
	int len;

	host = url_http_proxy_host;
	port = url_http_proxy_port;

	p = name;
	if(strncmp(p, "http://", 7) == 0)
	    p += 7;
	for(q = p; *q && *q != ':' && *q != '/'; q++)
	    ;
	len = q - p;
	if(len >= sizeof(wwwserver) - 1) { /* What?? */
	    strcpy(wwwserver, "localhost");
	} else {
	    strncpy(wwwserver, p, len);
	}
    }
    else
    {
	if(strncmp(name, "http://", 7) == 0)
	    name += 7;
	n = strlen(name);
	if(n + REQUEST_OFFSET >= BUFSIZ)
	{
	    url_http_close((URL)url);
	    url_errno = URLERR_URLTOOLONG;
	    errno = ENOENT;
	    return NULL;
	}

	memcpy(buff, name, n + 1);

	host = buff;
	for(p = host; *p && *p != ':' && *p != '/'; p++)
	    ;
	if(*p == ':')
	{
	    char *pp;

	    *p++ = '\0'; /* terminate `host' string */
	    port = atoi(p);
	    pp = strchr(p, '/');
	    if(pp == NULL)
		p[0] = '\0';
	    else
		p = pp;
	}
	else
	    port = 80;
	path = p;

	if(*path == '\0')
	    *(path + 1) = '\0';

	*path = '\0'; /* terminate `host' string */
	strncpy(wwwserver, host, sizeof(wwwserver));
    }

#ifdef DEBUG
    printf("open(host=`%s', port=`%d')\n", host, port);
#endif /* DEBUG */

#ifdef __W32__
    timeout_flag = 0;
    fd = open_socket(host, port);
#else
    timeout_flag = 0;
    signal(SIGALRM, timeout);
    alarm(ALARM_TIMEOUT);
    fd = open_socket(host, port);
    alarm(0);
    signal(SIGALRM, SIG_DFL);
#endif /* __W32__ */

    if(fd  == (SOCKET)-1)
    {
	VOLATILE_TOUCH(timeout_flag);
#ifdef ETIMEDOUT
	if(timeout_flag)
	    errno = ETIMEDOUT;
#endif /* ETIMEDOUT */
	if(errno)
	    url_errno = errno;
	else
	{
	    url_errno = URLERR_CANTOPEN;
	    errno = ENOENT;
	}
	url_http_close((URL)url);
	return NULL;
    }

    if((url->fp = socket_fdopen(fd, "rb")) == NULL)
    {
	url_errno = errno;
	closesocket(fd);
	url_http_close((URL)url);
	errno = url_errno;
	return NULL;
    }

    if(url_http_proxy_host)
	sprintf(buff, "GET %s HTTP/1.0\r\n", name);
    else
    {
	*path = '/';
	sprintf(buff, "GET %s HTTP/1.0\r\n", path);
    }
    socket_write(fd, buff, (long)strlen(buff));

#ifdef DEBUG
    printf("HTTP<%s", buff);
#endif /* DEBUG */

    if(url_user_agent)
    {
	sprintf(buff, "User-Agent: %s\r\n", url_user_agent);
	socket_write(fd, buff, (long)strlen(buff));
#ifdef DEBUG
	printf("HTTP<%s", buff);
#endif /* DEBUG */
    }

    /* Host field */
    sprintf(buff, "Host: %s\r\n", wwwserver);
    socket_write(fd, buff, (long)strlen(buff));
#ifdef DEBUG
    printf("HTTP<%s", buff);
#endif /* DEBUG */

    /* End of header */
    socket_write(fd, "\r\n", 2);
    socket_shutdown(fd, 1);

    if(socket_fgets(buff, BUFSIZ, url->fp) == NULL)
    {
	if(errno)
	    url_errno = errno;
	else
	{
	    url_errno = URLERR_CANTOPEN;
	    errno = ENOENT;
	}
	url_http_close((URL)url);
	return NULL;
    }

#ifdef DEBUG
    printf("HTTP>%s", buff);
#endif /* DEBUG */

    p = buff;
    if(strncmp(p, "HTTP/1.0 ", 9) == 0 || strncmp(p, "HTTP/1.1 ", 9) == 0)
	p += 9;
    if(strncmp(p, "200", 3) != 0) /* Not success */
    {
	url_http_close((URL)url);
	url_errno = errno = ENOENT;
	return NULL;
    }

    /* Skip mime header */
    while(socket_fgets(buff, BUFSIZ, url->fp) != NULL)
    {
	if(buff[0] == '\n' || (buff[0] == '\r' && buff[1] == '\n'))
	    break; /* end of heaer */
#ifdef DEBUG
	printf("HTTP>%s", buff);
#endif /* DEBUG */
    }

#ifdef __W32__
    return url_buff_open((URL)url, 1);
#else
    return (URL)url;
#endif /* __W32__ */
}
Example #22
0
static void *thread_client_to_device(void *data)
{
	socket_info_t* socket_info = (socket_info_t*)data;
	idevice_error_t res = IDEVICE_E_UNKNOWN_ERROR;

	int recv_len;
	int sent;
	char buffer[131072];
	thread_t dtoc;

	debug("%s: started thread...\n", __func__);

	debug("%s: client_fd = %d\n", __func__, socket_info->client_fd);
	debug("%s: server_fd = %d\n", __func__, socket_info->server_fd);

	/* spawn server to client thread */
	socket_info->stop_dtoc = 0;
	if (thread_create(&dtoc, thread_device_to_client, data) != 0) {
		fprintf(stderr, "Failed to start device to client thread...\n");
	}

	while (!quit_flag && !socket_info->stop_ctod && socket_info->client_fd > 0 && socket_info->server_fd > 0) {
		debug("%s: receiving data from client...\n", __func__);

		/* attempt to read incoming data from client */
		recv_len = socket_receive_timeout(socket_info->client_fd, buffer, sizeof(buffer), 0, 5000);

		/* any data received? */
		if (recv_len <= 0) {
			if (recv_len == 0) {
				/* try again */
				continue;
			} else {
				fprintf(stderr, "Receive failed: %s\n", strerror(errno));
				break;
			}
		} else {
			/* forward data to device */
			debug("%s: sending data to device...\n", __func__);
			res = idevice_connection_send(socket_info->device_connection, buffer, recv_len, (uint32_t*)&sent);

			if (sent < recv_len || res != IDEVICE_E_SUCCESS) {
				if (sent <= 0) {
					fprintf(stderr, "send failed: %s\n", strerror(errno));
					break;
				} else {
					fprintf(stderr, "only sent %d from %d bytes\n", sent, recv_len);
				}
			} else {
				// sending succeeded, receive from device
				debug("%s: sent %d bytes to device\n", __func__, sent);
			}
		}
	}

	debug("%s: shutting down...\n", __func__);

	socket_shutdown(socket_info->client_fd, SHUT_RDWR);
	socket_close(socket_info->client_fd);

	socket_info->client_fd = -1;
	socket_info->stop_dtoc = 1;

	/* join other thread to allow it to stop */
	thread_join(dtoc);

	return NULL;
}
Example #23
0
void do_tcp_tests(int timeout, int concurrency)
{
	int		selres;
	fd_set		readfds, writefds;
	struct timespec	timestamp;
	int 		absmaxconcurrency;

	int		activesockets = 0; /* Number of allocated sockets */
	int		pending = 0;	   /* Total number of tests */
	tcptest_t	*nextinqueue;      /* Points to the next item to start testing */
	tcptest_t	*firstactive;      /* Points to the first item currently being tested */
					   /* Thus, active connections are between firstactive..nextinqueue */
	tcptest_t	*item;
	int		sockok;
	int		maxfd;
	int		res;
	socklen_t	connressize;
	char		msgbuf[4096];

	struct rlimit lim;

	/* If timeout or concurrency are 0, set them to reasonable defaults */
	if (timeout == 0) timeout = 10;	/* seconds */

	/* 
	 * Decide how many tests to run in parallel.
	 * If no --concurrency set by user, default to (FD_SETSIZE / 4) - typically 256.
	 * But never go above the ressource limit that is set, or above FD_SETSIZE.
	 * And we save 10 fd's for stdio, libs etc.
	 */
	absmaxconcurrency = (FD_SETSIZE - 10);
	getrlimit(RLIMIT_NOFILE, &lim); 
	if ((lim.rlim_cur > 10) && ((lim.rlim_cur - 10) < absmaxconcurrency)) absmaxconcurrency = (lim.rlim_cur - 10);

	if (concurrency == 0) concurrency = (FD_SETSIZE / 4);
	if (concurrency > absmaxconcurrency) concurrency = absmaxconcurrency;

	dbgprintf("Concurrency evaluation: rlim_cur=%lu, FD_SETSIZE=%d, absmax=%d, initial=%d\n", 
		  lim.rlim_cur, FD_SETSIZE, absmaxconcurrency, concurrency);

	if (shuffletests) {
		struct timeval tv;
		struct timezone tz;
		gettimeofday(&tv, &tz);
		srandom(tv.tv_usec);
	}

	/* How many tests to do ? */
	for (item = thead; (item); item = item->next) {
		if (shuffletests) item->randomizer = random();
		pending++; 
	}
	if (shuffletests) thead = msort(thead, tcptest_compare, tcptest_getnext, tcptest_setnext);

	firstactive = nextinqueue = thead;
	dbgprintf("About to do %d TCP tests running %d in parallel, abs.max %d\n", 
		  pending, concurrency, absmaxconcurrency);

	while (pending > 0) {
		int slowrunning, cclimit;
		time_t slowtimestamp = gettimer() - SLOWLIMSECS;

		/*
		 * First, see if we need to allocate new sockets and initiate connections.
		 */

		/*
		 * We start by counting the number of tests where the latest activity
		 * happened more than SLOWLIMSECS seconds ago. These are ignored when counting
		 * how many more tests we can start concurrenly. But never exceed the absolute 
		 * max. number of concurrently open sockets possible.
		 */
		for (item=firstactive, slowrunning = 0; (item != nextinqueue); item=item->next) {
			if ((item->fd > -1) && (item->lastactive < slowtimestamp)) slowrunning++;
		}
		cclimit = concurrency + slowrunning; 
		if (cclimit > absmaxconcurrency) cclimit = absmaxconcurrency;

		sockok = 1;
		while (sockok && nextinqueue && (activesockets < cclimit)) {
			/*
			 * We need to allocate a new socket that has O_NONBLOCK set.
			 */
			nextinqueue->fd = socket(PF_INET, SOCK_STREAM, 0);
			sockok = (nextinqueue->fd != -1);
			if (sockok) {
				/* Set the source address */
				if (nextinqueue->srcaddr) {
					struct sockaddr_in src;
					int isip;

					memset(&src, 0, sizeof(src));
					src.sin_family = PF_INET;
					src.sin_port = 0;
					isip = (inet_aton(nextinqueue->srcaddr, (struct in_addr *) &src.sin_addr.s_addr) != 0);

					if (!isip) {
						char *envaddr = getenv(nextinqueue->srcaddr);
						isip = (envaddr && (inet_aton(envaddr, (struct in_addr *) &src.sin_addr.s_addr) != 0));
					}

					if (isip) {
						res = bind(nextinqueue->fd, (struct sockaddr *)&src, sizeof(src));
						if (res != 0) errprintf("WARNING: Could not bind to source IP %s for test %s: %s\n",
								nextinqueue->srcaddr, nextinqueue->tspec, strerror(errno));
					}
					else {
						errprintf("WARNING: Invalid source IP %s for test %s, using default\n",
								nextinqueue->srcaddr, nextinqueue->tspec);
					}
				}

				res = fcntl(nextinqueue->fd, F_SETFL, O_NONBLOCK);

				if (res == 0) {
					/*
					 * Initiate the connection attempt ... 
					 */
					getntimer(&nextinqueue->timestart);
					nextinqueue->lastactive = nextinqueue->timestart.tv_sec;
					nextinqueue->cutoff = nextinqueue->timestart.tv_sec + timeout + 1;
					res = connect(nextinqueue->fd, (struct sockaddr *)&nextinqueue->addr, sizeof(nextinqueue->addr));

					/*
					 * Did it work ?
					 */
					if ((res == 0) || ((res == -1) && (errno == EINPROGRESS))) {
						/* This is OK - EINPROGRES and res=0 pick up status in select() */
						activesockets++;
						tcp_stats_connects++;
					}
					else if (res == -1) {
						/* connect() failed. Flag the item as "not open" */
						nextinqueue->connres = errno;
						nextinqueue->open = 0;
						nextinqueue->errcode = CONTEST_ENOCONN;
						close(nextinqueue->fd);
						nextinqueue->fd = -1;
						pending--;

						switch (nextinqueue->connres) {
						   /* These may happen if connection is refused immediately */
						   case ECONNREFUSED : break;
						   case EHOSTUNREACH : break;
						   case ENETUNREACH  : break;
						   case EHOSTDOWN    : break;

						   /* Not likely ... */
						   case ETIMEDOUT    : break;

						   /* These should not happen. */
						   case EBADF        : errprintf("connect returned EBADF!\n"); break;
						   case ENOTSOCK     : errprintf("connect returned ENOTSOCK!\n"); break;
						   case EADDRNOTAVAIL: errprintf("connect returned EADDRNOTAVAIL!\n"); break;
						   case EAFNOSUPPORT : errprintf("connect returned EAFNOSUPPORT!\n"); break;
						   case EISCONN      : errprintf("connect returned EISCONN!\n"); break;
						   case EADDRINUSE   : errprintf("connect returned EADDRINUSE!\n"); break;
						   case EFAULT       : errprintf("connect returned EFAULT!\n"); break;
						   case EALREADY     : errprintf("connect returned EALREADY!\n"); break;
						   default           : errprintf("connect returned %d, errno=%d\n", res, errno);
						}
					}
					else {
						/* Should NEVER happen. connect returns 0 or -1 */
						errprintf("Strange result from connect: %d, errno=%d\n", res, errno);
					}
				}
				else {
					/* Could net set to non-blocking mode! Hmmm ... */
					sockok = 0;
					errprintf("Cannot set O_NONBLOCK\n");
				}

				nextinqueue=nextinqueue->next;
			}
			else {
				int newconcurrency = ((activesockets > 5) ? (activesockets-1) : 5);

				/* Could not get a socket */
				switch (errno) {
				   case EPROTONOSUPPORT: errprintf("Cannot get socket - EPROTONOSUPPORT\n"); break;
				   case EAFNOSUPPORT   : errprintf("Cannot get socket - EAFNOSUPPORT\n"); break;
				   case EMFILE         : errprintf("Cannot get socket - EMFILE\n"); break;
				   case ENFILE         : errprintf("Cannot get socket - ENFILE\n"); break;
				   case EACCES         : errprintf("Cannot get socket - EACCESS\n"); break;
				   case ENOBUFS        : errprintf("Cannot get socket - ENOBUFS\n"); break;
				   case ENOMEM         : errprintf("Cannot get socket - ENOMEM\n"); break;
				   case EINVAL         : errprintf("Cannot get socket - EINVAL\n"); break;
				   default             : errprintf("Cannot get socket - errno=%d\n", errno); break;
				}

				if (newconcurrency != concurrency) {
					errprintf("Reducing --concurrency setting from %d to %d\n", 
							concurrency, newconcurrency);
					concurrency = newconcurrency;
				}
			}
		}

		/* Ready to go - we have a bunch of connections being established */
		dbgprintf("%d tests pending - %d active tests, %d slow tests\n", 
			  pending, activesockets, slowrunning);

restartselect:
		/*
		 * Setup the FDSET's
		 */
		FD_ZERO(&readfds); FD_ZERO(&writefds); maxfd = -1;
		for (item=firstactive; (item != nextinqueue); item=item->next) {
			if (item->fd > -1) {
				/*
				 * WRITE events are used to signal that a
				 * connection is ready, or it has been refused.
				 * READ events are only interesting for sockets
				 * that have already been found to be open, and
				 * thus have the "readpending" flag set.
				 *
				 * So: On any given socket, we want either a 
				 * write-event or a read-event - never both.
				 */
				if (item->readpending)
					FD_SET(item->fd, &readfds);
				else 
					FD_SET(item->fd, &writefds);

				if (item->fd > maxfd) maxfd = item->fd;
			}
		}

		if (maxfd == -1) {
			/* No active connections */
			if (activesockets == 0) {
				/* This can happen, if we get an immediate CONNREFUSED on all connections. */
				continue;
			}
			else {
				errprintf("contest logic error: No FD's, active=%d, pending=%d\n",
					  activesockets, pending);
				continue;
			}
		}
				
		/*
		 * Wait for something to happen: connect, timeout, banner arrives ...
		 */
		if (maxfd < 0) {
			errprintf("select - no active fd's found, but pending is %d\n", pending);
			selres = 0;
		}
		else {
			struct timeval tmo = { 1, 0 };
			dbgprintf("Doing select with maxfd=%d\n", maxfd);
			selres = select((maxfd+1), &readfds, &writefds, NULL, &tmo);
			dbgprintf("select returned %d\n", selres);
		}

		if (selres == -1) {
			int selerr = errno;

			/*
			 * select() failed - this is BAD!
			 */
			switch (selerr) {
			   case EINTR : errprintf("select failed - EINTR\n"); goto restartselect;
			   case EBADF : errprintf("select failed - EBADF\n"); break;
			   case EINVAL: errprintf("select failed - EINVAL\n"); break;
			   case ENOMEM: errprintf("select failed - ENOMEM\n"); break;
			   default    : errprintf("Unknown select() error %d\n", selerr); break;
			}

			/* Leave this mess ... */
			errprintf("Aborting TCP tests with %d tests pending\n", pending);
			return;
		}

		/* selres == 0 (timeout) isn't special - just go through the list of active tests */

		/* Fetch the timestamp so we can tell how long the connect took */
		getntimer(&timestamp);

		/* Now find out which connections had something happen to them */
		for (item=firstactive; (item != nextinqueue); item=item->next) {
			if (item->fd > -1) {		/* Only active sockets have this */
				if (timestamp.tv_sec > item->cutoff) {
					/* 
					 * Request timed out.
					 */
					if (item->readpending) {
						/* Final read timeout - just shut this socket */
						socket_shutdown(item);
						item->errcode = CONTEST_ETIMEOUT;
					}
					else {
						/* Connection timeout */
						item->open = 0;
						item->errcode = CONTEST_ETIMEOUT;
					}
					get_totaltime(item, &timestamp);
					close(item->fd);
					item->fd = -1;
					activesockets--;
					pending--;
					if (item == firstactive) firstactive = item->next;
				}
				else {
					if (FD_ISSET(item->fd, &writefds)) {
						int do_talk = 1;
						unsigned char *outbuf = NULL;
						unsigned int outlen = 0;

						item->lastactive = timestamp.tv_sec;

						if (!item->open) {
							/*
							 * First time here.
							 *
							 * Active response on this socket - either OK, or 
							 * connection refused.
							 * We determine what happened by getting the SO_ERROR status.
							 * (cf. select_tut(2) manpage).
							 */
							connressize = sizeof(item->connres);
							res = getsockopt(item->fd, SOL_SOCKET, SO_ERROR, &item->connres, &connressize);
							item->open = (item->connres == 0);
							if (!item->open) item->errcode = CONTEST_ENOCONN;
							do_talk = item->open;
							get_connectiontime(item, &timestamp);
						}

						if (item->open && (item->svcinfo->flags & TCP_SSL)) {
							/* 
							 * Setup the SSL connection, if not done already.
							 *
							 * NB: This can be triggered many times, as setup_ssl()
							 * may need more data from the remote and return with
							 * item->sslrunning == SSLSETUP_PENDING
							 */
							if (item->sslrunning == SSLSETUP_PENDING) {
								setup_ssl(item);
								if (item->sslrunning == 1) {
									/*
									 * Update connectiontime to include
									 * time for SSL handshake.
									 */
									get_connectiontime(item, &timestamp);
								}
							}
							do_talk = (item->sslrunning == 1);
						}

						/*
						 * Connection succeeded - port is open, if SSL then the
						 * SSL handshake is complete. 
						 *
						 * If we have anything to send then send it.
						 * If we want the banner, set the "readpending" flag to initiate
						 * select() for read()'s.
						 * NB: We want the banner EITHER if the GET_BANNER flag is set,
						 *     OR if we need it to match the expect string in the servicedef.
						 */

						item->readpending = (do_talk && !item->silenttest && 
							( (item->svcinfo->flags & TCP_GET_BANNER) || item->svcinfo->exptext ));
						if (do_talk) {
							if (item->telnetnegotiate && item->telnetbuflen) {
								/*
								 * Return the telnet negotiate data response
								 */
								outbuf = item->telnetbuf;
								outlen = item->telnetbuflen;
							}
							else if (item->sendtxt && !item->silenttest) {
								outbuf = item->sendtxt;
								outlen = (item->sendlen ? item->sendlen : strlen(outbuf));
							}

							if (outbuf && outlen) {
								/*
								 * It may be that we cannot write all of the
								 * data we want to. Tough ... 
								 */
								res = socket_write(item, outbuf, outlen);
								tcp_stats_written += res;
								if (res == -1) {
									/* Write failed - this socket is done. */
									dbgprintf("write failed\n");
									item->readpending = 0;
									item->errcode = CONTEST_EIO;
								}
								else if (item->svcinfo->flags & TCP_HTTP) {
									/*
									 * HTTP tests require us to send the full buffer.
									 * So adjust sendtxt/sendlen accordingly.
									 * If no more to send, switch to read-mode.
									 */
									item->sendtxt += res;
									item->sendlen -= res;
									item->readpending = (item->sendlen == 0);
								}
							}
						}

						/* If closed and/or no bannergrabbing, shut down socket */
						if (item->sslrunning != SSLSETUP_PENDING) {
							if (!item->open || !item->readpending) {
								if (item->open) {
									socket_shutdown(item);
								}
								close(item->fd);
								get_totaltime(item, &timestamp);
								if (item->finalcallback) item->finalcallback(item->priv);
								item->fd = -1;
								activesockets--;
								pending--;
								if (item == firstactive) firstactive = item->next;
							}
						}
					}
					else if (FD_ISSET(item->fd, &readfds)) {
						/*
						 * Data ready to read on this socket. Grab the
						 * banner - we only do one read (need the socket
						 * for other tests), so if the banner takes more
						 * than one cycle to arrive, too bad!
						 */
						int wantmoredata = 0;
						int datadone = 0;

						item->lastactive = timestamp.tv_sec;

						/*
						 * We may be in the process of setting up an SSL connection
						 */
						if (item->sslrunning == SSLSETUP_PENDING) setup_ssl(item);
						if (item->sslrunning == SSLSETUP_PENDING) break;  /* Loop again waiting for more data */

						/*
						 * Connection is ready - plain or SSL. Read data.
						 */
						res = socket_read(item, msgbuf, sizeof(msgbuf)-1);
						tcp_stats_read += res;
						dbgprintf("read %d bytes from socket\n", res);

						if ((res > 0) && item->datacallback) {
							datadone = item->datacallback(msgbuf, res, item->priv);
						}

						if ((res > 0) && item->telnetnegotiate) {
							/*
							 * telnet data has telnet options first.
							 * We must negotiate the session before we
							 * get the banner.
							 */
							item->telnetbuf = item->banner;
							item->telnetbuflen = res;

							/*
							 * Safety measure: Dont loop forever doing
							 * telnet options.
							 * This puts a maximum on how many times
							 * we go here.
							 */
							item->telnetnegotiate--;
							if (!item->telnetnegotiate) {
								dbgprintf("Max. telnet negotiation (%d) reached for host %s\n", 
									MAX_TELNET_CYCLES,
									inet_ntoa(item->addr.sin_addr));
							}

							if (do_telnet_options(item)) {
								/* Still havent seen the session banner */
								item->banner = NULL;
								item->bannerbytes = 0;
								item->readpending = 0;
								wantmoredata = 1;
							}
							else {
								/* No more options - we have the banner */
								item->telnetnegotiate = 0;
							}
						}

						if ((item->svcinfo->flags & TCP_HTTP) && 
						    ((res > 0) || item->sslagain)     &&
						    (!datadone) ) {
							/*
							 * HTTP : Grab the entire response.
							 */
							wantmoredata = 1;
						}

						if (!wantmoredata) {
							if (item->open) {
								socket_shutdown(item);
							}
							item->readpending = 0;
							close(item->fd);
							get_totaltime(item, &timestamp);
							if (item->finalcallback) item->finalcallback(item->priv);
							item->fd = -1;
							activesockets--;
							pending--;
							if (item == firstactive) firstactive = item->next;
						}
					}
				}
			}
		}  /* end for loop */
	} /* end while (pending) */

	dbgprintf("TCP tests completed normally\n");
}
Example #24
0
int start_server (int argc, char *argv[])
{
    int      i;
    int      threadCount = 0;
    int      thread_id;
    HANDLE   g_hThread[MAX_THREAD];
    char     doers_number[MAXDOER][SPACE_FOR_THREAD_ID];
    char     movers_number[MAXMOVER][SPACE_FOR_THREAD_ID];

#ifdef INFORMIX
    MI_CONNECTION_INFO conn_info;

    // This works around a bug in Informix's isqlt09a.dll that causes memory
    // access violation when our program exits.
    memset (&conn_info, '\0', sizeof (conn_info));
    mi_server_connect (&conn_info);
#endif
    // Don't let the user start the middleware server as a standalone program.
    // Check whether the argument matches the magic string.
    if ((argc != 2) || (stricmp(argv[1], SERVER_MAGIC_STR) != 0))
    {
        puts("Vigilert Middleware Server cannot be started as a standalone program.");
        puts("Start the Velara Vigilert service.\n");
        Sleep (4000);
        exit(EXIT_FAILURE);
    }

    // Assign IDs to the multiple movers and doers
    for (i = 0; i < MAXDOER; i++)
    {
        sprintf (doers_number[i], "%d", i + 1);
    }

    for (i = 0; i < MAXMOVER; i++)
    {
        sprintf (movers_number[i], "%d", i + 1);
    }

    /* Initialize the global variables */
    num_doer = 0;
    num_mover = 0;
    g_fTerminate = FALSE;
    num_doers_accessing_global_SPI = 0;

    puts ("\n.:. Vigilert Server .:.");

    // Save the memory state so we can diff against it in vl_gather_stats.
    _CrtMemCheckpoint (&s1);

    // Initialize the mutexes
    InitializeCriticalSection(&suspend_mutex);
    InitializeCriticalSection(&mover_cleaner_mutex);
    InitializeCriticalSection(&doer_num_mutex);
    InitializeCriticalSection(&mover_num_mutex);
    InitializeCriticalSection(&num_doers_accessing_global_SPI_mutex);
    InitializeCriticalSection(&Global_SPI_mutex);

#ifdef _MIDDLE
    init_named_mem();
#endif

    load_keys();

#ifdef _MIDDLE
    InitializeCriticalSection(&logwrite_mutex);
    InitializeCriticalSection(&begin_udr_mutex);
    tm_init_conn_pool();
#endif

    // Initialize the semaphores that wakeup the movers and the doers

    // Doers can be woken up by doer dispatcher, mover (that moves the database tokens
    // to the database task queue) and the TCP-IP server thread that builds and moves the stream
    // tokens to the stream task queue.
    wakeup_doer_by_doer_dispatcher_sem = CreateSemaphore(NULL, 0, MAXDOER, NULL);    // Semaphore for doer-dispatcher
    wakeup_doer_by_mover_sem = CreateSemaphore(NULL, 0, MAXDOER, NULL);              // Semaphore for mover
    wakeup_doer_by_tcpip_server_sem = CreateSemaphore(NULL, 0, MAXDOER, NULL);       // Semahpore for TCP-IP server
    // Mover can be wpken up by mover dispatcher.
    wakeup_mover_by_mover_dispatcher_sem = CreateSemaphore(NULL, 0, MAXMOVER, NULL); // Semaphore for mover-dispatcher

    // Initialize the array of semaphore handles that can wake up the doers
    wakeup_doer_array[0] = wakeup_doer_by_doer_dispatcher_sem;
    wakeup_doer_array[1] = wakeup_doer_by_mover_sem;
    wakeup_doer_array[2] = wakeup_doer_by_tcpip_server_sem;

    // Initialize the event variable to say whether a command execute thread is waiting to access global SPI.
    command_execute_waiting_event = CreateEvent(NULL, TRUE, TRUE, NULL);

    /* start threads */
    g_hThread[threadCount] = chBEGINTHREADEX(NULL, 0, wait_end, NULL, CREATE_SUSPENDED, &thread_id);
    tm_associate_thread_id_to_connection(threadCount, thread_id);
    threadCount++;

    g_hThread[threadCount] = chBEGINTHREADEX(NULL, 0, mover_dispatcher, NULL, CREATE_SUSPENDED, &thread_id);
    tm_associate_thread_id_to_connection(threadCount, thread_id);
    threadCount++;

    g_hThread[threadCount] = chBEGINTHREADEX(NULL, 0, doer_dispatcher, NULL, CREATE_SUSPENDED, &thread_id);
    tm_associate_thread_id_to_connection(threadCount, thread_id);
    threadCount++;

    g_hThread[threadCount] = chBEGINTHREADEX(NULL, 0, TCPIPserver, NULL, CREATE_SUSPENDED, &thread_id);
    tm_associate_thread_id_to_connection(threadCount, thread_id);
    threadCount++;

    g_hThread[threadCount] = chBEGINTHREADEX(NULL, 0, cleaner, NULL, CREATE_SUSPENDED, &thread_id);
    tm_associate_thread_id_to_connection(threadCount, thread_id);
    threadCount++;

#ifdef _DEBUG
    g_hThread[threadCount] = chBEGINTHREADEX(NULL, 0, GatherStatsServer, NULL, CREATE_SUSPENDED, &thread_id);
    tm_associate_thread_id_to_connection(threadCount, thread_id);
    threadCount++;
#endif

    for (i = 0; i < MAXDOER; i++)
    {
        g_hThread[threadCount] = chBEGINTHREADEX(NULL, 0, doer,(LPVOID)doers_number[i], CREATE_SUSPENDED,  &thread_id);
        tm_associate_thread_id_to_connection(threadCount, thread_id);
        threadCount++;
    }

    for (i = 0; i < MAXMOVER; i++)
    {
        g_hThread[threadCount] = chBEGINTHREADEX(NULL, 0, mover,(LPVOID)movers_number[i], CREATE_SUSPENDED,  &thread_id);
        tm_associate_thread_id_to_connection(threadCount, thread_id);
        threadCount++;
    }

    // Before starting the various threads, let the main thread run the initializing routine
    // to initialize all main memory data structures
    tm_associate_thread_id_to_connection(threadCount, tm_get_thread_id());

    tman_init();

    // Resume the various suspended threads one by one
    for (i = 0; i < threadCount; i++)
    {
        int result;
        result = ResumeThread(g_hThread[i]);
        if (result == -1)
        {
#ifdef _MIDDLE
            printf ("Error: unable to start thread %d.\n", tm_own_connpool_1[i].thread_id);
#endif
            exit (EXIT_FAILURE);
        }
    }

    // Wait for all the currently active threads to die or terminate before performing the cleanup
    // of all main memory objects and exiting the middleware server
    WaitForMultipleObjects(threadCount, g_hThread, TRUE, INFINITE);

    for (i = 0; i< threadCount; i++)
        CloseHandle(g_hThread[i]);

    DeleteCriticalSection(&mover_num_mutex);
    DeleteCriticalSection(&doer_num_mutex);
    DeleteCriticalSection(&mover_cleaner_mutex);
    DeleteCriticalSection(&suspend_mutex);
    DeleteCriticalSection(&num_doers_accessing_global_SPI_mutex);
    DeleteCriticalSection(&Global_SPI_mutex);

    CloseHandle(wakeup_mover_by_mover_dispatcher_sem);
    CloseHandle(wakeup_doer_by_doer_dispatcher_sem);
    CloseHandle(wakeup_doer_by_tcpip_server_sem);
    CloseHandle(wakeup_doer_by_mover_sem);
    CloseHandle(command_execute_waiting_event);

#ifdef _MIDDLE
    {
        tm_close_conn_pool();
        close_named_mem();
        DeleteCriticalSection(&begin_udr_mutex);
        DeleteCriticalSection(&logwrite_mutex);
        socket_shutdown();
    }
#endif

    puts ("Vigilert run complete.");
    return EXIT_SUCCESS;
}