Exemple #1
0
void launch_server() {
    int i; /* Re-usable loop variable. */

    /* Try opening a socket */
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0) {
        printf("%s\n", "ERROR opening socket\n");
        return;
    } /* couldn't open a socket */

    struct sockaddr_in serv_address, client_address;
    serv_address.sin_family = AF_INET;
    serv_address.sin_addr.s_addr = getpublicaddress();
    serv_address.sin_port = 0; /* want a random port number */
    unsigned int len_address = sizeof(serv_address);


    /* Bind socket to the host IP address and a random portno. */
    if (mybind(sockfd, &serv_address) < 0) {
        printf("%s", "Unable to bind socket to IP and port number\n");
        perror("bind: ");
        return;
    } /* couldn't bind the socket to an IP address/port */

    getsockname(sockfd, (struct sockaddr *) &serv_address, &len_address);

    printf("%s %d \n", inet_ntoa(serv_address.sin_addr),
                       serv_address.sin_port);

    /* Listen and queue incoming requests. */
    listen(sockfd, /* max queue size */ 3);

    while (1) {
        /* Try accepting an incoming connection. */
        int newfd = accept(sockfd, (struct sockaddr *) &client_address,
                                    &len_address);
        if (newfd < 0) {
            printf("%s\n", "ERROR on accept\n");
            continue;
        } /* not able to accept an incoming connection. */

        /* Read request data into the buffer. */
        if (read(newfd, buffer, BUFFER_LENGTH) < 0) {
            printf("%s\n", "ERROR reading from socket\n");
            continue;
        }

        BYTE *ptr = buffer; /* pointer used to iterate through the buffer */

        /* account for NULL character in length */
        int procedure_name_length = strlen(ptr) + 1;
        ptr += procedure_name_length;

        int nparams = *(int *)ptr;
        ptr += sizeof(int);

        /* Search for the registered procedure. */
        bool found_proc = 0;    /* indicates that we've found the target procedure */
        stored_procedure proc;
        for (i = 0; i < num_procs; ++i) {
            if (strcmp(buffer, proc_list[i].procedure_name) == 0) {
                proc = proc_list[i];
                found_proc = 1;
                break;
            }  /* if we found the registered procedure */
        }

        if (!found_proc) {
            printf("%s", "ERROR requested procedure not found!");
            continue;
        } /* if we didn't find the registered procedure */

        if (proc.nparams != nparams) {
            printf("Expected %d parameters, Got %d \n", proc.nparams,
                                                        nparams);
            continue;
        } /* if the number of params sent don't match what we expected */

        arg_type args_head;
        arg_type *arg = &args_head;
        args_head.next = NULL;
        for (i = 0; i < nparams; i++, arg = arg->next) {
            arg->arg_size = *(int *)ptr; ptr += sizeof(int);
            arg->arg_val = (void *)ptr;  ptr += arg->arg_size;
            if (i < nparams - 1) {
                arg->next = (arg_type *)malloc(sizeof(arg_type));
            } /* if we're not in the last parameter */
            else {
                arg->next = NULL;
            } /* we're in the last parameter */
        }

        return_type r = proc.fnpointer(nparams, &args_head);
        ptr = buffer;
        *(int *)ptr = r.return_size;
        ptr += sizeof(int);
        memcpy(ptr, r.return_val, r.return_size);
        if (write(newfd, buffer, BUFFER_LENGTH) < 0) {
            printf("%s\n", "ERROR writing to socket");
            continue;
        }

        /* free memory allocated for param list */
        arg_type* current = args_head.next;
        while (current != NULL) {
            arg_type* next = current->next;
            free(current);
            current = next;
        }
    } /* end forever */
}
Exemple #2
0
void webserver ()
{
  // Setup server behaviour.
  config_globals_client_prepared = config_logic_client_prepared ();
  if (strcmp (DEMO, "yes") == 0) config_globals_open_installation = true;

  // Create a listening socket.
  int listenfd = socket(AF_INET, SOCK_STREAM, 0);
  if (listenfd < 0) cerr << "Error opening socket: It returns a descriptor of " << listenfd << endl;

  // Eliminate "Address already in use" error from bind.
  int optval = 1;
  int result = setsockopt (listenfd, SOL_SOCKET, SO_REUSEADDR, (const char *) &optval, sizeof (int));
  if (result != 0) cerr << "Error setting socket options" << endl;

  // The listening socket will be an endpoint for all requests to a port on any IP address for this host.
  typedef struct sockaddr SA;
  struct sockaddr_in serveraddr;
  memset (&serveraddr, 0, sizeof (serveraddr));
  serveraddr.sin_family = AF_INET;
  serveraddr.sin_addr.s_addr = htonl (INADDR_ANY);
  serveraddr.sin_port = htons (convert_to_int (config_logic_network_port ()));
  result = mybind (listenfd, (SA *) &serveraddr, sizeof (serveraddr));
  if (result != 0) cerr << "Error binding server to socket" << endl;

  // Make it a listening socket ready to accept many connection requests.
  result = listen (listenfd, 100);
  if (result != 0) cerr << "Error listening on socket" << endl;

  // Ignore SIGPIPE signal: When the browser cancels the request, it won't kill Bibledit.
  signal (SIGPIPE, SIG_IGN);

  // Keep waiting for, accepting, and processing connections.
  config_globals_running = true;
  while (config_globals_running) {

    // Socket and file descriptor for the client connection.
    struct sockaddr_in clientaddr;
    socklen_t clientlen = sizeof(clientaddr);
    int connfd = accept (listenfd, (SA *)&clientaddr, &clientlen);
    if (connfd > 0) {

      // Socket receive timeout.
      struct timeval tv;
      tv.tv_sec = 60;
      tv.tv_usec = 0;
      setsockopt (connfd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
      
      // The client's remote IPv4 address in dotted notation.
      char remote_address[256];
      inet_ntop (AF_INET, &clientaddr.sin_addr.s_addr, remote_address, sizeof (remote_address));
      string clientaddress = remote_address;
      
      // Handle this request in a thread, enabling parallel requests.
      thread request_thread = thread (webserver_process_request, connfd, clientaddress);
      // Detach and delete thread object.
      request_thread.detach ();
      
    } else {
      cerr << "Error accepting connection on socket" << endl;
    }
  }
  
  // Close listening socket, freeing it for a possible subsequent server process.
  close (listenfd);
}
/**
 * @brief This function starts the server listening for requests for function calls
 *        to functions registered by the server stub.
 */
void launch_server()
{
    int socket_descriptor;                    ///< Stores a files descriptor pertaining to a server socket.
    int recv_size_bytes;                      ///< Stores the number of bytes received from the client.
    char* server_ip_addr;                     ///< The IPv4 address of the server.
    struct sockaddr_in s_server_sockaddr_in;  ///< Stores the server socket and port.
    struct sockaddr_in s_client_sockaddr_in;  ///< Stores the client socket and port.
    void* p_recv_buffer;                      ///< The buffer containing the remote procedure call arguments from the client.
    void* p_recv_buffer_offset;               ///< Pointer to the current value in p_recv_buffer.
    void* p_send_buffer;                      ///< The buffer containing the return value for the client.
    void* p_send_buffer_offset;               ///< Pointer to the current value in p_send_buffer.
    socklen_t addrlen;                        ///< Stores the length of s_client_sockaddr_in.
    unsigned int idx;                         ///< An index for for loops.
    arg_type* sp_arg_type_list_head;          ///< Points to the remote procedure call argument linked list.
    arg_type* sp_current_arg_type_element;    ///< Pointer to the current arg in the arg_type linked list.
    arg_type** sp_arg_type_array;             ///< An array of argtype* pointers to each arg in the arg_type linked list.
    fp_type p_fnpointer;                      ///< Call function pointer.
    return_type s_return_type;                ///< Stores the return value pertaining to the remote procedure call.

    // Establish server socket
    socket_descriptor = socket( AF_INET, SOCK_DGRAM, 0 );
    
    // If socket not established successfully, exit program.
    if( socket_descriptor < 0 )
    {
        perror( "Could not create server socket." );
        exit( 1 );
    }

    // Obtain the IP address of the current machine
    server_ip_addr = return_ip_addr();
    
    // Configure the server socket address and port number. Server can accept responses on all network interfaces.
    memset( ( char* )&s_server_sockaddr_in, 0, sizeof( s_server_sockaddr_in ) );
    s_server_sockaddr_in.sin_family = AF_INET;
    s_server_sockaddr_in.sin_addr.s_addr = htonl( INADDR_ANY );

    // Bind address and port number to UDP socket. If bind unsuccessful, exit program.
    if (mybind(socket_descriptor, &s_server_sockaddr_in) < 0)
    {
        perror("Could not bind address and port number to server socket.");
        exit( 1 );
    }
    
    // Print server IPv4 address and port number to stdout.
    printf( "%s %d\n", server_ip_addr, ntohs( s_server_sockaddr_in.sin_port ) );

    // Gets the length of s_client_sockaddr_in
    addrlen = sizeof( s_client_sockaddr_in );

    // Allocates a block of memory for incoming client RPC arguments.
    p_recv_buffer = malloc(BUFFER_SIZE);

    // Loop forever.
    while( true )
    {
        // Attempt to receive request from client.
        recv_size_bytes = recvfrom(socket_descriptor, p_recv_buffer, BUFFER_SIZE, 0, (struct sockaddr*)&s_client_sockaddr_in, &addrlen);
        
        if (recv_size_bytes <= 0)
        {
            // If could not receive request from client, set RPC return value to NULL.
            perror( "Could not receive UDP packet from client." );
            s_return_type.return_size = 0;
            s_return_type.return_val = NULL;
        }
        else if (recv_size_bytes > 0)
        {
            // Read RPC arguments from client. 
            p_recv_buffer_offset = p_recv_buffer;
            size_t procedure_name_len = *(uint32_t*)p_recv_buffer_offset;
            p_recv_buffer_offset = ( void* )( ( char* )p_recv_buffer_offset + sizeof( size_t ) );
            char* procedure_name = ( char* )p_recv_buffer_offset;
            p_recv_buffer_offset = ( void* )(( char* )p_recv_buffer_offset + procedure_name_len );
            uint32_t nparams = *(uint32_t*)p_recv_buffer_offset;
            p_recv_buffer_offset = ( void* )( ( char* )p_recv_buffer_offset + sizeof( uint32_t ) );

            sp_arg_type_list_head = NULL;
            sp_current_arg_type_element = sp_arg_type_list_head;
            sp_arg_type_array = (arg_type**)malloc(sizeof(arg_type*) * nparams);

            for (idx = 0; idx < nparams; idx++)
            {
                arg_type* s_arg_type = (arg_type *)malloc(sizeof(arg_type));
                s_arg_type->arg_size = *( size_t* )p_recv_buffer_offset;
                p_recv_buffer_offset = ( void* )( ( char* )p_recv_buffer_offset + sizeof( size_t ) );
                
                s_arg_type->arg_val = malloc(s_arg_type->arg_size);
                memcpy(s_arg_type->arg_val, p_recv_buffer_offset, s_arg_type->arg_size);
                p_recv_buffer_offset = (void*)((char*)p_recv_buffer_offset + s_arg_type->arg_size);
                s_arg_type->next = NULL;
                sp_arg_type_array[idx] = s_arg_type;
                
                if( sp_arg_type_list_head == NULL )
                {
                    sp_arg_type_list_head = s_arg_type;
                    sp_current_arg_type_element = sp_arg_type_list_head;
                }
                else
                {
                    sp_current_arg_type_element->next = s_arg_type;
                    sp_current_arg_type_element = sp_current_arg_type_element->next;
                }
            }

            // Get registered function pointer from given procedure_name.
            p_fnpointer = map_procedure_name_to_fnpointer( procedure_name );
            
            if (p_fnpointer != NULL)
            {
                // Call function pointed to by p_fnpointer if registered function exists and pass in RPC argument linked list.
                s_return_type = (*p_fnpointer)(nparams, sp_arg_type_list_head);
            }
            else
            {
                // Set RPC return value to NULL if registered function does not exist.
                s_return_type.return_size = 0;
                s_return_type.return_val = NULL;
            }

            // Deallocate memory for each arg in the RPC argument linked list.
            for(idx = 0; idx < nparams; idx++)
            {
                free(sp_arg_type_array[idx]->arg_val);
                free(sp_arg_type_array[idx]);
            }
            
            // Deallocate memory for the sp_arg_type_array.
            free(sp_arg_type_array);
        }

        // Place return value into p_send_buffer.
        p_send_buffer = malloc(sizeof(size_t) + s_return_type.return_size);
        p_send_buffer_offset = p_send_buffer;
        memcpy( p_send_buffer_offset, &( s_return_type.return_size ), sizeof( size_t ) );
        p_send_buffer_offset = ( void* )( ( char* )p_send_buffer_offset + sizeof( size_t ) );
        
        // Copy the RPC return value iff the return size is greater than 0.
        if (s_return_type.return_size > 0)
        {
            memcpy( p_send_buffer_offset, s_return_type.return_val, s_return_type.return_size );
            p_send_buffer_offset = ( void* )( ( char* )p_send_buffer_offset + s_return_type.return_size );
        }
        
        // Send the RPC return value to the client.
        if (sendto(socket_descriptor, p_send_buffer, sizeof(size_t)+s_return_type.return_size, 0, (struct sockaddr*)&s_client_sockaddr_in, addrlen) < 0)
        {
            perror("Could not return result to client.");
        }

        // Deallocate memory for the p_send_buffer.
        free(p_send_buffer);
    }
}
void launch_server() {
    int s = socket(AF_INET, SOCK_STREAM, 0);
    struct sockaddr_in a;

    memset(&a, 0, sizeof(struct sockaddr_in));
    a.sin_family = AF_INET;
    a.sin_port = 0;
    if((a.sin_addr.s_addr = getPublicIPAddr()) == 0) {
	fprintf(stderr, "Could not get public ip address. Exiting...\n");
	exit(0);
    }

    if(mybind(s, &a) < 0) {
	fprintf(stderr, "mybind() failed. Exiting...\n");
	exit(0);
    }

    printf("%s %u\n", inet_ntoa(a.sin_addr), ntohs(a.sin_port));
    
    if(listen(s, 0) < 0) {
	perror("listen"); exit(0);
    }

    memset(&a, 0, sizeof(struct sockaddr_in));
    socklen_t alen = sizeof(struct sockaddr_in);
    int asock = -1;
    while((asock = accept(s, (struct sockaddr *)&a, &alen)) > 0) {
	/* Single-threaded */

	char *fname;
	int nparams;
	arg_type *a = NULL;
	return_type ret;

	recvCall(asock, &fname, &nparams, &a);

#ifdef _DEBUG_1_
	printf("launch_server(), before makeCall()\n"); fflush(stdout);
#endif

	makeCall(fname, nparams, a, &ret);

#ifdef _DEBUG_1_
	printf("launch_server(), after makeCall()\n"); fflush(stdout);
#endif

	returnResult(asock, &ret);

	free(fname);
	freeArgs(a);
	freeRet(ret);

	shutdown(asock, SHUT_RDWR); close(asock);
	asock = -1;
    }

    /* WARNING -- massive memory, linked list of registered
     * functions! We assume that the process exits at this
     * point, and so do not bother freeing the memory. */
    return;
}
Exemple #5
0
int
main(int argc, char *argv[])
{
    struct sockaddr_in sin;
    mysocket_t bindsd;
    int len, opt, errflg = 0;
    char localname[256];


    /* Parse the command line */
    while ((opt = getopt(argc, argv, "")) != EOF)
    {
        switch (opt)
        {
        case '?':
            ++errflg;
            break;
        }
    }

    if (errflg || optind != argc)
    {
        fprintf(stderr, usage, argv[0]);
        exit(EXIT_FAILURE);
    }

    /* open connection on any available port */
    if ((bindsd = mysocket()) < 0)
    {
        perror("mysocket");
        exit(EXIT_FAILURE);
    }

    memset(&sin, 0, sizeof(sin));
    sin.sin_family = AF_INET;
    sin.sin_addr.s_addr = htonl(INADDR_ANY);
    sin.sin_port = htons(0);
    len = sizeof(struct sockaddr_in);

    if (mybind(bindsd, (struct sockaddr *) &sin, len) < 0)
    {
        perror("mybind");
        exit(EXIT_FAILURE);
    }

    if (mylisten(bindsd, 5) < 0)
    {
        perror("mylisten");
        exit(EXIT_FAILURE);
    }
    if (local_name(bindsd, localname) < 0)
    {
        perror("local_name");
        exit(EXIT_FAILURE);
    }
    fprintf(stderr, "Server's address is %s\n", localname);
    fflush(stderr);

    for (;;)
    {
        mysocket_t sd;

        /* just keep accepting connections forever */
        if ((sd = myaccept(bindsd, (struct sockaddr *) &sin, &len)) < 0)
        {
            perror("myaccept");
            exit(EXIT_FAILURE);
        }

        assert(sin.sin_family == AF_INET);
        fprintf(stderr, "connected to %s at port %u\n",
                inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));

        do_connection(sd);
    }                           /* end for(;;) */

    if (myclose(bindsd) < 0)
        perror("myclose (bindsd)");
    return 0;
}