Exemplo n.º 1
0
// Establish a connection using an SSL layer
void ssl_connect(mongo_link* link, SV *client) {
  tcp_setup(link);

  SV *ca_file_sv, *ca_path_sv;
  char *ca_file, *ca_path;

  if (link->master->socket){
    // Register the error strings for libcrypto & libssl
    SSL_load_error_strings();

    // Register the available ciphers and digests
    SSL_library_init();

    // New context saying we are a client, and using SSL 2 or 3
    link->ssl_context = SSL_CTX_new(SSLv23_client_method());
    if(link->ssl_context == NULL){
      ERR_print_errors_fp(stderr);
    }

    ca_file_sv = perl_mongo_call_method( client, "ssl_ca_file", 0, 0 );
    ca_path_sv = perl_mongo_call_method( client, "ssl_ca_path", 0, 0 );

    if ( SvPOK( ca_file_sv ) && SvPOK( ca_path_sv ) ) { 
      ca_file = SvPV_nolen( ca_file_sv );
      ca_path = SvPV_nolen( ca_path_sv );

      SSL_CTX_load_verify_locations( link->ssl_context, ca_file, ca_path );
    }

    // Create an SSL struct for the connection
    link->ssl_handle = SSL_new(link->ssl_context);
    if(link->ssl_handle == NULL){
      ERR_print_errors_fp(stderr);
    }

    // Connect the SSL struct to our connection
    if(!SSL_set_fd(link->ssl_handle, link->master->socket)){
      ERR_print_errors_fp(stderr);
    }

    // Initiate SSL handshake
    if(SSL_connect (link->ssl_handle) != 1){
      ERR_print_errors_fp(stderr);
    }

    SSL_CTX_set_timeout(link->ssl_context, (long)link->timeout);

    link->master->connected = 1;
  }
}
Exemplo n.º 2
0
// Establish a connection using an SSL layer
void ssl_connect(mongo_link* link) {
  tcp_setup(link);

  if (link->master->socket){
    // Register the error strings for libcrypto & libssl
    SSL_load_error_strings();

    // Register the available ciphers and digests
    SSL_library_init();

    // New context saying we are a client, and using SSL 2 or 3
    link->ssl_context = SSL_CTX_new(SSLv23_client_method());
    if(link->ssl_context == NULL){
      ERR_print_errors_fp(stderr);
    }

    // Create an SSL struct for the connection
    link->ssl_handle = SSL_new(link->ssl_context);
    if(link->ssl_handle == NULL){
      ERR_print_errors_fp(stderr);
    }

    // Connect the SSL struct to our connection
    if(!SSL_set_fd(link->ssl_handle, link->master->socket)){
      ERR_print_errors_fp(stderr);
    }

    // Initiate SSL handshake
    if(SSL_connect (link->ssl_handle) != 1){
      ERR_print_errors_fp(stderr);
    }

    SSL_CTX_set_timeout(link->ssl_context, (long)link->timeout);

    link->master->connected = 1;
  }
}
Exemplo n.º 3
0
int main(int argc, char **argv)
{
	int udp_socket;
	int tcp_socket;
	int tcp_port;

	int client_socket;

	struct sockaddr_in addr;
	int addr_size;

	char buffer[1025];

	struct client *clients;

	int num_clients;
	int max_clients;

	int i, j;
	int len;
	char* temp_str;

	fd_set read_fds_master;
	fd_set read_fds_copy;
	int fd_max;

	FD_ZERO(&read_fds_master);
	FD_ZERO(&read_fds_copy);

	clients = malloc(BACKLOG * sizeof(struct client));
	num_clients = 0;
	max_clients = BACKLOG;

	
	/* signal(SIGINT, handle_sigint); */


	if ((udp_socket = udp_setup(UDP_PORT)) == -1) exit(1);

	/* make udp socket "select()able" */
	FD_SET(udp_socket, &read_fds_master);
	fd_max = udp_socket;

	if((tcp_socket = tcp_setup(&tcp_port)) == -1) exit(1);
	printf("Listening on tcp port: %d\n", tcp_port);

	/* make tcp socket "select()able" */
	FD_SET(tcp_socket, &read_fds_master);
	fd_max = tcp_socket;


	/* main loop */
	for (;;)
	{
		/* handle readable sockets */
		read_fds_copy = read_fds_master; // make a copy that select() can modify
		if (select(fd_max + 1, &read_fds_copy, NULL, NULL, NULL) == -1)
		{
			fprintf(stderr, "Error during select().\n");
			close(udp_socket);
			exit(1);
		}

		for (i = 0; i <= fd_max; i++)
		{
			if (FD_ISSET(i, &read_fds_copy))
			{
				if (i == udp_socket)
				{
					/* answer a multicast message */
					memset(buffer, 0, sizeof(buffer));
					addr_size = sizeof(addr);
					if (recvfrom(udp_socket, buffer, sizeof(buffer), 0, (struct sockaddr*)&addr, &addr_size) == -1)
					{
						fprintf(stderr, "Error receiving multicast message.\n");
						close(udp_socket);
						exit(1);
					}


					if (strncmp(buffer, "server_discovery", 16) == 0)
					{
						printf("%s:%d - discovery request\n", inet_ntoa(addr.sin_addr.s_addr), ntohs(addr.sin_port));
						len = sprintf(buffer, "discovery_reply %d\n", tcp_port);
						addr_size = sizeof(addr);
						if (sendto(udp_socket, buffer, len, 0, (struct sockaddr*)&addr, addr_size) == -1)
						{
							perror("Error answering multicast message.\n");
							close(udp_socket);
							exit(1);
						}
					}
				}
				if (i == tcp_socket)
				{
					for (j = 0; j < num_clients; j++)
					{
						if (clients[j].status == 'd') break; /* the value of j at this point is used as a side effect later */
					}
					/* j is now ALWAYS the first unused index of the clients array */
					if (j == num_clients) num_clients++;

					if (num_clients > max_clients)
					{
						max_clients = max_clients + BACKLOG;
						clients = realloc(clients, max_clients * sizeof(struct client));
					}
					addr_size = sizeof(addr);
					clients[j].socket = accept(tcp_socket, (struct sockaddr*)&addr, &addr_size);
					clients[j].status = 'c';

					/* save source as string for logging and debugging */
					strncpy(clients[j].socket_addr, (const char*)inet_ntoa(addr.sin_addr.s_addr), 15);
					clients[j].socket_port = ntohs(addr.sin_port);
					printf("%s:%d - new connection.\n", clients[j].socket_addr, clients[j].socket_port);
					FD_SET(clients[j].socket, &read_fds_master);
					if (clients[j].socket > fd_max) fd_max = clients[j].socket;
				}
				for (j = 0; j < num_clients; j++)
				{
					if (i == clients[j].socket)
					{
						memset(buffer, 0, sizeof(buffer));
						len = recv(clients[j].socket, buffer, sizeof(buffer) - 1 - strlen(clients[j].line_buffer), 0);
						switch (len)
						{
						case 0:
							printf("%s:%d - disconnected.\n", clients[j].socket_addr, clients[j].socket_port);
							FD_CLR(clients[j].socket, &read_fds_master);
							clients[j].status = 'd';
							push_global_filelist(clients, num_clients);
							break;
						case -1:
							/* TODO: handle gracefully. this is usually a "connection reset by peer" */
							perror("recv");
							break;
						default:
							strncat(clients[j].line_buffer, buffer, len);

							while (strchr(clients[j].line_buffer, '\n') != NULL)
							{
								switch (clients[j].status)
								{
								case 'c':
									//printf("status: connected\n");
									if (sscanf(clients[j].line_buffer, "register %d", &(clients[j].download_port)) == 1)
									{
										printf("%s:%d - registered port %d for downloads.\n", clients[j].socket_addr, clients[j].socket_port, clients[j].download_port);
										clients[j].status = 'r';
										break;
									}
									printf("%s:%d - sent %d unrecognized bytes: %s\n", clients[j].socket_addr, clients[j].socket_port, strlen(clients[j].line_buffer), clients[j].line_buffer);
									break;
								case 'r':
									//printf("status: registered\n");
									//printf("buffer: %s", clients[j].line_buffer);
									if (sscanf(clients[j].line_buffer, "send_filelist %d\n", &(clients[j].filelist_size)) == 1)
									{
										if (clients[j].filelist_size > 0)
										{
											printf("%s:%d - will send %d file list entries next.\n", clients[j].socket_addr, clients[j].socket_port, clients[j].filelist_size);
											if (clients[j].file_list != NULL) free(clients[j].file_list);
											clients[j].file_list = malloc(clients[j].filelist_size * sizeof(struct filelist_entry));
										}

										clients[j].status = 's';
										clients[j].filelist_len = 0;
									break;
									}
									if (strncmp(clients[j].line_buffer, "unregister", 10) == 0)
									{
										printf("%s:%d - unregistered download port.\n", clients[j].socket_addr, clients[j].socket_port);
										clients[j].status = 'c';
										break;
									}
									printf("%s:%d - sent %d unrecognized bytes: %s\n", clients[j].socket_addr, clients[j].socket_port, strlen(clients[j].line_buffer), clients[j].line_buffer);
									break;
								case 's':
									//printf("status: sending file list\n");
									if (clients[j].filelist_len < clients[j].filelist_size)
									{	
										len = clients[j].filelist_len;
										if (sscanf(clients[j].line_buffer , "%d %1000s", &(clients[j].file_list[len].size), clients[j].file_list[len].name) == 2)
										{
											clients[j].filelist_len = clients[j].filelist_len + 1;
											printf("%s:%d - sent a file list entry: %s (%d bytes)\n", clients[j].socket_addr, clients[j].socket_port, clients[j].file_list[len].name, clients[j].file_list[len].size);

										}
										else
										{
											printf("%s:%d - sent %d unrecognized bytes: %s\n", clients[j].socket_addr, clients[j].socket_port, strlen(clients[j].line_buffer), clients[j].line_buffer);
										}
									}
									if (clients[j].filelist_len == clients[j].filelist_size)
									{
										clients[j].status = 'r';
										push_global_filelist(clients, num_clients);
									}
									break;
								default:
									break;
								}

								/* consume part of buffer */
								temp_str = strchr(clients[j].line_buffer, '\n');
								//printf("bytes left: %d\n", strlen(temp_str));
								if (strlen(temp_str) > 1)
								{
									memset(buffer, 0, sizeof(buffer));
									strncpy(buffer, temp_str + 1, strlen(temp_str) - 1);
									//printf("bytes left: %d\n", strlen(buffer));
									memset(clients[j].line_buffer, 0, sizeof(clients[j].line_buffer));
									strncpy(clients[j].line_buffer, buffer, strlen(buffer));
									//printf("line buffer: %s", clients[j].line_buffer);
								}
								else
								{
									memset(clients[j].line_buffer, 0, sizeof(clients[j].line_buffer));
								}
							}
						}
					}
				}
			}
		}
	}
}
Exemplo n.º 4
0
int
main(int argc, char *argv[])
{
	char *dummy;
	int sock[2];
	long port;

	if (argc != 2)
		usage();

	port = strtol(argv[1], &dummy, 10);
	if (port < 0 || port > 65535 || *dummy != '\0')
		usage();

#ifndef SO_NOSIGPIPE
	warnx("sigpipe: SO_NOSIGPIPE not defined, skipping some tests");
#endif

	/*
	 * UNIX domain socketpair().
	 */
	if (socketpair(PF_LOCAL, SOCK_STREAM, 0, sock) < 0)
		err(-1, "socketpair(PF_LOCAL, SOCK_STREAM)");
	test_send_wantsignal("test_send_wantsignal(PF_LOCAL)", sock[0],
	    sock[1]);

#ifdef SO_NOSIGPIPE
	if (socketpair(PF_LOCAL, SOCK_STREAM, 0, sock) < 0)
		err(-1, "socketpair(PF_LOCAL, SOCK_STREAM)");
	test_send_dontsignal("test_send_dontsignal(PF_LOCAL)", sock[0],
	    sock[1]);
#endif

	if (socketpair(PF_LOCAL, SOCK_STREAM, 0, sock) < 0)
		err(-1, "socketpair(PF_LOCAL, SOCK_STREAM)");
	test_write_wantsignal("test_write_wantsignal(PF_LOCAL)", sock[0],
	    sock[1]);

#ifdef SO_NOSIGPIPE
	if (socketpair(PF_LOCAL, SOCK_STREAM, 0, sock) < 0)
		err(-1, "socketpair(PF_LOCAL, SOCK_STREAM)");
	test_write_dontsignal("test_write_dontsignal(PF_LOCAL)", sock[0],
	    sock[1]);
#endif

	/*
	 * TCP.
	 */
	tcp_setup(port);
	tcp_pair(port, sock);
	test_send_wantsignal("test_send_wantsignal(PF_INET)", sock[0],
	    sock[1]);

#ifdef SO_NOSIGPIPE
	tcp_pair(port, sock);
	test_send_dontsignal("test_send_dontsignal(PF_INET)", sock[0],
	    sock[1]);
#endif

	tcp_pair(port, sock);
	test_write_wantsignal("test_write_wantsignal(PF_INET)", sock[0],
	    sock[1]);

#ifdef SO_NOSIGPIPE
	tcp_pair(port, sock);
	test_write_dontsignal("test_write_dontsignal(PF_INET)", sock[0],
	    sock[1]);
#endif
	tcp_teardown();

	fprintf(stderr, "PASS\n");
	return (0);
}
Exemplo n.º 5
0
Arquivo: main.c Projeto: huayl/pelikan
static void
setup(void)
{
    char *fname = NULL;
    uint64_t intvl;

    if (atexit(teardown) != 0) {
        log_stderr("cannot register teardown procedure with atexit()");
        exit(EX_OSERR); /* only failure comes from NOMEM */
    }

    /* Setup logging first */
    log_setup(&stats.log);
    if (debug_setup(&setting.debug) != CC_OK) {
        log_stderr("debug log setup failed");
        exit(EX_CONFIG);
    }

    /* setup top-level application options */
    if (option_bool(&setting.ds.daemonize)) {
        daemonize();
    }
    fname = option_str(&setting.ds.pid_filename);
    if (fname != NULL) {
        /* to get the correct pid, call create_pidfile after daemonize */
        create_pidfile(fname);
    }

    /* setup library modules */
    buf_setup(&setting.buf, &stats.buf);
    dbuf_setup(&setting.dbuf, &stats.dbuf);
    event_setup(&stats.event);
    sockio_setup(&setting.sockio, &stats.sockio);
    tcp_setup(&setting.tcp, &stats.tcp);
    timing_wheel_setup(&stats.timing_wheel);

    /* setup pelikan modules */
    time_setup(&setting.time);
    procinfo_setup(&stats.procinfo);
    request_setup(&setting.request, &stats.request);
    response_setup(&setting.response, &stats.response);
    parse_setup(&stats.parse_req, NULL);
    compose_setup(NULL, &stats.compose_rsp);
    slab_setup(&setting.slab, &stats.slab);
    process_setup(&setting.process, &stats.process);
    admin_process_setup();
    core_admin_setup(&setting.admin);
    core_server_setup(&setting.server, &stats.server);
    core_worker_setup(&setting.worker, &stats.worker);

    /* adding recurring events to maintenance/admin thread */
    intvl = option_uint(&setting.ds.dlog_intvl);
    if (core_admin_register(intvl, debug_log_flush, NULL) == NULL) {
        log_stderr("Could not register timed event to flush debug log");
        goto error;
    }

    return;

error:
    if (fname != NULL) {
        remove_pidfile(fname);
    }

    /* since we registered teardown with atexit, it'll be called upon exit */
    exit(EX_CONFIG);
}