From 0f99d1f2201f70ae688b1bfd8a33c503ece42cb1 Mon Sep 17 00:00:00 2001 From: hniksic Date: Thu, 13 Nov 2003 09:05:06 -0800 Subject: [PATCH] [svn] Rewrote bindport and acceptport to use a more standard calling convention. --- src/ChangeLog | 7 +++++ src/connect.c | 76 +++++++++++++++++++++++++++++++++---------------- src/connect.h | 4 +-- src/ftp-basic.c | 24 ++++++++-------- src/ftp.c | 19 ++++++------- src/wget.h | 3 +- 6 files changed, 82 insertions(+), 51 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index 49670ff5..068f92b3 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,10 @@ +2003-11-13 Hrvoje Niksic + + * connect.c (bind_local): Renamed bindport to bind_local; return + the socket directly. Updated callers. + (accept_connection): Renamed acceptport to accept_connection; + return the created socket directly. Updated callers. + 2003-11-13 Hrvoje Niksic * init.c (defaults): Turn on opt.ipv4_only if we're compiling with diff --git a/src/connect.c b/src/connect.c index 90729aec..46b0aa02 100644 --- a/src/connect.c +++ b/src/connect.c @@ -404,12 +404,21 @@ test_socket_open (int sock) #endif } -/* Create a socket and bind it to PORT locally. Calling accept() on - such a socket waits for and accepts incoming TCP connections. The - resulting socket is stored to LOCAL_SOCK. */ +/* Create a socket, bind it to local interface BIND_ADDRESS on port + *PORT, set up a listen backlog, and return the resulting socket, or + -1 in case of error. -uerr_t -bindport (const ip_address *bind_address, int *port, int *local_sock) + BIND_ADDRESS is the address of the interface to bind to. If it is + NULL, the socket is bound to the default address. PORT should + point to the port number that will be used for the binding. If + that number is 0, the system will choose a suitable port, and the + chosen value will be written to *PORT. + + Calling accept() on such a socket waits for and accepts incoming + TCP connections. */ + +int +bind_local (const ip_address *bind_address, int *port) { int sock; int family = AF_INET; @@ -426,8 +435,9 @@ bindport (const ip_address *bind_address, int *port, int *local_sock) family = AF_INET6; #endif - if ((sock = socket (family, SOCK_STREAM, 0)) < 0) - return CONSOCKERR; + sock = socket (family, SOCK_STREAM, 0); + if (sock < 0) + return -1; #ifdef SO_REUSEADDR setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, setopt_ptr, setopt_size); @@ -445,16 +455,22 @@ bindport (const ip_address *bind_address, int *port, int *local_sock) if (bind (sock, sa, sockaddr_size (sa)) < 0) { xclose (sock); - return BINDERR; + return -1; } DEBUGP (("Local socket fd %d bound.\n", sock)); - if (!*port) + + /* If *PORT is 0, find out which port we've bound to. */ + if (*port == 0) { socklen_t sa_len = sockaddr_size (sa); if (getsockname (sock, sa, &sa_len) < 0) { + /* If we can't find out the socket's local address ("name"), + something is seriously wrong with the socket, and it's + unusable for us anyway because we must know the chosen + port. */ xclose (sock); - return CONPORTERR; + return -1; } sockaddr_get_data (sa, NULL, port); DEBUGP (("binding to address %s using port %i.\n", @@ -463,10 +479,9 @@ bindport (const ip_address *bind_address, int *port, int *local_sock) if (listen (sock, 1) < 0) { xclose (sock); - return LISTENERR; + return -1; } - *local_sock = sock; - return BINDOK; + return sock; } #ifdef HAVE_SELECT @@ -504,27 +519,40 @@ select_fd (int fd, double maxtime, int wait_for) } #endif /* HAVE_SELECT */ -/* Accept a connection on LOCAL_SOCK, and store the new socket to - *SOCK. It blocks the caller until a connection is established. If - no connection is established for opt.connect_timeout seconds, the +/* Like a call to accept(), but with the added check for timeout. + + In other words, accept a client connection on LOCAL_SOCK, and + return the new socket used for communication with the client. + LOCAL_SOCK should have been bound, e.g. using bind_local(). + + The caller is blocked until a connection is established. If no + connection is established for opt.connect_timeout seconds, the function exits with an error status. */ -uerr_t -acceptport (int local_sock, int *sock) +int +accept_connection (int local_sock) { + int sock; + + /* We don't need the values provided by accept, but accept + apparently requires them to be present. */ struct sockaddr_storage ss; struct sockaddr *sa = (struct sockaddr *)&ss; socklen_t addrlen = sizeof (ss); #ifdef HAVE_SELECT if (opt.connect_timeout) - if (select_fd (local_sock, opt.connect_timeout, WAIT_FOR_READ) <= 0) - return ACCEPTERR; + { + int test = select_fd (local_sock, opt.connect_timeout, WAIT_FOR_READ); + if (test == 0) + errno = ETIMEDOUT; + if (test <= 0) + return -1; + } #endif - if ((*sock = accept (local_sock, sa, &addrlen)) < 0) - return ACCEPTERR; - DEBUGP (("Created socket fd %d.\n", *sock)); - return ACCEPTOK; + sock = accept (local_sock, sa, &addrlen); + DEBUGP (("Accepted client at socket %d.\n", sock)); + return sock; } /* Get the IP address associated with the connection on FD and store diff --git a/src/connect.h b/src/connect.h index a0c830c6..9d67d070 100644 --- a/src/connect.h +++ b/src/connect.h @@ -47,8 +47,8 @@ enum { int connect_to_host PARAMS ((const char *, int)); int connect_to_ip PARAMS ((const ip_address *, int, const char *)); -uerr_t bindport PARAMS ((const ip_address *, int *, int *)); -uerr_t acceptport PARAMS ((int, int *)); +int bind_local PARAMS ((const ip_address *, int *)); +int accept_connection PARAMS ((int)); enum { ENDPOINT_LOCAL, diff --git a/src/ftp-basic.c b/src/ftp-basic.c index 350d3103..56cb4de2 100644 --- a/src/ftp-basic.c +++ b/src/ftp-basic.c @@ -286,7 +286,7 @@ ftp_port (struct rbuf *rbuf, int *local_sock) /* Get the address of this side of the connection. */ if (!socket_ip_address (RBUF_FD (rbuf), &addr, ENDPOINT_LOCAL)) - return BINDERR; + return FTPSYSERR; assert (addr.type == IPV4_ADDRESS); @@ -294,9 +294,9 @@ ftp_port (struct rbuf *rbuf, int *local_sock) port = 0; /* Bind the port. */ - err = bindport (&addr, &port, local_sock); - if (err != BINDOK) - return err; + *local_sock = bind_local (&addr, &port); + if (*local_sock < 0) + return FTPSYSERR; /* Construct the argument of PORT (of the form a,b,c,d,e,f). */ ip_address_to_port_repr (&addr, port, bytes, sizeof (bytes)); @@ -383,7 +383,7 @@ ftp_lprt (struct rbuf *rbuf, int *local_sock) /* Get the address of this side of the connection. */ if (!socket_ip_address (RBUF_FD (rbuf), &addr, ENDPOINT_LOCAL)) - return BINDERR; + return FTPSYSERR; assert (addr.type == IPV4_ADDRESS || addr.type == IPV6_ADDRESS); @@ -391,9 +391,9 @@ ftp_lprt (struct rbuf *rbuf, int *local_sock) port = 0; /* Bind the port. */ - err = bindport (&addr, &port, local_sock); - if (err != BINDOK) - return err; + *local_sock = bind_local (&addr, &port); + if (*local_sock < 0) + return FTPSYSERR; /* Construct the argument of LPRT (of the form af,n,h1,h2,...,hn,p1,p2). */ ip_address_to_lprt_repr (&addr, port, bytes, sizeof (bytes)); @@ -467,7 +467,7 @@ ftp_eprt (struct rbuf *rbuf, int *local_sock) /* Get the address of this side of the connection. */ if (!socket_ip_address (RBUF_FD (rbuf), &addr, ENDPOINT_LOCAL)) - return BINDERR; + return FTPSYSERR; assert (addr.type == IPV4_ADDRESS || addr.type == IPV6_ADDRESS); @@ -475,9 +475,9 @@ ftp_eprt (struct rbuf *rbuf, int *local_sock) port = 0; /* Bind the port. */ - err = bindport (&addr, &port, local_sock); - if (err != BINDOK) - return err; + *local_sock = bind_local (&addr, &port); + if (*local_sock < 0) + return FTPSYSERR; /* Construct the argument of LPRT (of the form af,n,h1,h2,...,hn,p1,p2). */ ip_address_to_eprt_repr (&addr, port, bytes, sizeof (bytes)); diff --git a/src/ftp.c b/src/ftp.c index adc74a1e..21b023c2 100644 --- a/src/ftp.c +++ b/src/ftp.c @@ -705,8 +705,8 @@ Error in server response, closing control connection.\n")); if (!pasv_mode_open) /* Try to use a port command if PASV failed */ { err = ftp_do_port (&con->rbuf, &local_sock); - /* FTPRERR, WRITEFAILED, bindport (CONSOCKERR, CONPORTERR, BINDERR, - LISTENERR), HOSTERR, FTPPORTERR */ + /* FTPRERR, WRITEFAILED, bindport (FTPSYSERR), HOSTERR, + FTPPORTERR */ switch (err) { case FTPRERR: @@ -738,13 +738,11 @@ Error in server response, closing control connection.\n")); rbuf_uninitialize (&con->rbuf); return err; break; - case CONPORTERR: case BINDERR: case LISTENERR: - /* What now? These problems are local... */ + case FTPSYSERR: logputs (LOG_VERBOSE, "\n"); logprintf (LOG_NOTQUIET, _("Bind error (%s).\n"), strerror (errno)); xclose (dtsock); - xclose (local_sock); return err; break; case FTPPORTERR: @@ -963,10 +961,10 @@ Error in server response, closing control connection.\n")); if (!pasv_mode_open) /* we are not using pasive mode so we need to accept */ { - /* Open the data transmission socket by calling acceptport(). */ - err = acceptport (local_sock, &dtsock); - /* Possible errors: ACCEPTERR. */ - if (err == ACCEPTERR) + /* Wait for the server to connect to the address we're waiting + at. */ + dtsock = accept_connection (local_sock); + if (dtsock < 0) { logprintf (LOG_NOTQUIET, "accept: %s\n", strerror (errno)); return err; @@ -1261,8 +1259,7 @@ ftp_loop_internal (struct url *u, struct fileinfo *f, ccon *con) return err; break; case CONSOCKERR: case CONERROR: case FTPSRVERR: case FTPRERR: - case WRITEFAILED: case FTPUNKNOWNTYPE: case CONPORTERR: - case BINDERR: case LISTENERR: case ACCEPTERR: + case WRITEFAILED: case FTPUNKNOWNTYPE: case FTPSYSERR: case FTPPORTERR: case FTPLOGREFUSED: case FTPINVPASV: printwhat (count, opt.ntry); /* non-fatal errors */ diff --git a/src/wget.h b/src/wget.h index 059c830c..6cdfbeb0 100644 --- a/src/wget.h +++ b/src/wget.h @@ -210,8 +210,7 @@ typedef enum { NOCONERROR, HOSTERR, CONSOCKERR, CONERROR, CONSSLERR, CONIMPOSSIBLE, NEWLOCATION, NOTENOUGHMEM, CONPORTERR, - BINDERR, BINDOK, LISTENERR, ACCEPTERR, ACCEPTOK, - CONCLOSED, FTPOK, FTPLOGINC, FTPLOGREFUSED, FTPPORTERR, + CONCLOSED, FTPOK, FTPLOGINC, FTPLOGREFUSED, FTPPORTERR, FTPSYSERR, FTPNSFOD, FTPRETROK, FTPUNKNOWNTYPE, FTPRERR, FTPREXC, FTPSRVERR, FTPRETRINT, FTPRESTFAIL, URLERROR, FOPENERR, FWRITEERR, HOK, HLEXC, HEOF, -- 2.39.2