root/maint/gnulib/tests/socket-server.h

/* [previous][next][first][last][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. create_server
  2. create_server_socket

   1 /* Create sockets for use in tests (server side).
   2    Copyright (C) 2011-2021 Free Software Foundation, Inc.
   3 
   4    This program is free software: you can redistribute it and/or modify
   5    it under the terms of the GNU General Public License as published by
   6    the Free Software Foundation; either version 3 of the License, or
   7    (at your option) any later version.
   8 
   9    This program is distributed in the hope that it will be useful,
  10    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12    GNU General Public License for more details.
  13 
  14    You should have received a copy of the GNU General Public License
  15    along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
  16 
  17 /* Written by Bruno Haible <bruno@clisp.org>, 2011.  */
  18 
  19 #include <stdio.h>
  20 #include <sys/socket.h>
  21 #include <netinet/in.h>
  22 #include <arpa/inet.h>
  23 
  24 /* Creates a server that can be used to listen on incoming
  25    connections.  It uses the IPv4 protocol.
  26    If PORT is 0, a port is assigned by the kernel.
  27    Returns the server.  Returns the chosen port in *PPORT.  */
  28 static int
  29 create_server (int port, unsigned int max_backlog, int *pport)
     /* [previous][next][first][last][top][bottom][index][help] */
  30 {
  31   int server;
  32 
  33   /* Create a server socket.  */
  34   server = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP);
  35   if (server < 0)
  36     {
  37       fputs ("Skipping test: cannot create server socket: socket() failed\n",
  38              stderr);
  39       exit (77);
  40     }
  41   /* Bind it to a local IPv4 address.  */
  42   if (port != 0)
  43     {
  44       /* Set an option for the next bind() call: Avoid an EADDRINUSE error
  45          in case there are TIME_WAIT or CLOSE_WAIT sockets hanging around on
  46          the port. (Sockets in LISTEN or ESTABLISHED state on the same port
  47          will still yield an error.)  */
  48       unsigned int flag = 1;
  49       if (setsockopt (server, SOL_SOCKET, SO_REUSEADDR, &flag,
  50                       sizeof (flag))
  51           < 0)
  52         {
  53           fputs ("Skipping test: cannot create server socket: setsockopt() failed\n",
  54                  stderr);
  55           exit (77);
  56         }
  57     }
  58   {
  59     struct sockaddr_in addr;
  60 
  61     memset (&addr, 0, sizeof (addr)); /* needed on AIX and OSF/1 */
  62     addr.sin_family = AF_INET;
  63     #if 0 /* Unoptimized */
  64     inet_pton (AF_INET, "127.0.0.1", &addr.sin_addr);
  65     #elif 0 /* Nearly optimized */
  66     addr.sin_addr.s_addr = htonl (0x7F000001); /* 127.0.0.1 */
  67     #else /* Fully optimized */
  68     {
  69       unsigned char dotted[4] = { 127, 0, 0, 1 }; /* 127.0.0.1 */
  70       memcpy (&addr.sin_addr.s_addr, dotted, 4);
  71     }
  72     #endif
  73     addr.sin_port = htons (port);
  74 
  75     if (bind (server, (const struct sockaddr *) &addr, sizeof (addr)) < 0)
  76       {
  77         fputs ("Skipping test: cannot create server socket: bind() failed\n",
  78                stderr);
  79         exit (77);
  80       }
  81   }
  82   if (port == 0)
  83     {
  84       /* Get the port that was assigned by bind().  */
  85       struct sockaddr_in addr;
  86       socklen_t addrlen = sizeof (addr);
  87 
  88       if (getsockname (server, (struct sockaddr *) &addr, &addrlen) < 0)
  89         {
  90           fputs ("Skipping test: cannot create server socket: getsockname() failed\n",
  91                  stderr);
  92           exit (77);
  93         }
  94       port = ntohs (addr.sin_port);
  95     }
  96   /* Start listening for a connection from the child process.  */
  97   if (listen (server, max_backlog) < 0)
  98     {
  99       fputs ("Skipping test: cannot create server socket: listen() failed\n",
 100              stderr);
 101       exit (77);
 102     }
 103 
 104   *pport = port;
 105   return server;
 106 }
 107 
 108 /* Creates a server socket, by accepting a connection to a server.  */
 109 static int
 110 create_server_socket (int server)
     /* [previous][next][first][last][top][bottom][index][help] */
 111 {
 112   struct sockaddr_storage addr;
 113   socklen_t addrlen = sizeof (addr);
 114   int connected_socket = accept (server, (struct sockaddr *) &addr, &addrlen);
 115   ASSERT (connected_socket >= 0);
 116   return connected_socket;
 117 }

/* [previous][next][first][last][top][bottom][index][help] */