* Licensed under the GPL v2. For licencing details see COPYING.
*/
-/** \file net.c networking-related helper functions */
+/** \file net.c Networking-related helper functions. */
+
+#include <netdb.h> /* hostent */
#include "para.h"
#include "error.h"
static unsigned cda_size = 0;
/**
- * activate encryption for one file descriptor
+ * Activate encryption for one file descriptor.
*
- * \param fd the file descriptor
- * \param recv_f the function used for decrypting received data
- * \param send_f the function used for encrypting before sending
- * \param private_data user data supplied by the caller
+ * \param fd The file descriptor.
+ * \param recv_f The function used for decrypting received data.
+ * \param send_f The function used for encrypting before sending.
+ * \param private_data User data supplied by the caller.
*/
void enable_crypt(int fd, crypt_function *recv_f, crypt_function *send_f,
void *private_data)
}
/**
- * deactivate encryption for a given fd
+ * Deactivate encryption for a given fd.
*
- * \param fd the file descriptor
+ * \param fd The file descriptor.
*
* This must be called if and only if \p fd was activated via enable_crypt().
*/
/**
- * initialize a struct sockaddr_in
+ * Initialize a struct sockaddr_in.
*
- * \param addr A pointer to the struct to be initialized
- * \param port The port number to use
- * \param he The address to use
+ * \param addr A pointer to the struct to be initialized.
+ * \param port The port number to use.
+ * \param he The address to use.
*
* If \a he is null (server mode), \a addr->sin_addr is initialized with \p
* INADDR_ANY. Otherwise, the address given by \a he is copied to addr.
*/
-void init_sockaddr(struct sockaddr_in *addr, int port, const struct hostent *he)
+static void init_sockaddr(struct sockaddr_in *addr, int port, const struct hostent *he)
{
/* host byte order */
addr->sin_family = AF_INET;
}
/**
- * receive and decrypt.
+ * Receive and decrypt.
*
- * \param fd the file descriptor
- * \param buf the buffer to write the decrypted data to
- * \param size the size of \a buf
+ * \param fd The file descriptor.
+ * \param buf The buffer to write the decrypted data to.
+ * \param size The size of \a buf.
*
* Receive at most \a size bytes from file descriptor \a fd. If encryption is
* available, decrypt the received buffer.
}
/**
- * receive, decrypt and write terminating NULL byte
+ * Receive, decrypt and write terminating NULL byte.
*
- * \param fd the file descriptor
- * \param buf the buffer to write the decrypted data to
- * \param size the size of \a buf
+ * \param fd The file descriptor.
+ * \param buf The buffer to write the decrypted data to.
+ * \param size The size of \a buf.
*
* Read and decrypt at most \a size - 1 bytes from file descriptor \a fd and
* write a NULL byte at the end of the received data.
*
- * \return: The return value of the underlying call to \a recv_bin_buffer().
+ * \return The return value of the underlying call to \a recv_bin_buffer().
*
* \sa recv_bin_buffer()
*/
}
/**
- * wrapper around gethostbyname
+ * Establish a tcp connection.
*
- * \param host hostname or IPv4 address
- * \param ret the hostent structure is returned here
+ * \param host Hostname or IPv4 address.
+ * \param port The tcp port.
*
- * \return positive on success, negative on errors. On success, \a ret
- * contains the return value of the underlying gethostbyname() call.
- *
- * \sa gethostbyname(2)
+ * \return Negative on errors, a valid file descriptor on success.
*/
-int get_host_info(char *host, struct hostent **ret)
+int tcp_connect(char *host, int port)
{
+ struct sockaddr_in addr;
+ struct hostent *he;
+ int ret, fd;
+
PARA_INFO_LOG("getting host info of %s\n", host);
/* FIXME: gethostbyname() is obsolete */
- *ret = gethostbyname(host);
- return *ret? 1 : -E_HOST_INFO;
+ he = gethostbyname(host);
+ if (!he)
+ return -ERRNO_TO_PARA_ERROR(h_errno);
+ init_sockaddr(&addr, port, he);
+ ret = get_stream_socket(AF_INET);
+ if (ret < 0)
+ return ret;
+ fd = ret;
+ ret = PARA_CONNECT(fd, &addr);
+ if (ret >= 0)
+ return fd;
+ close(fd);
+ return ret;
}
/**
*
* \param domain The communication domain that selects the protocol family.
*
- * \return The socket fd on success, -E_SOCKET on errors.
- *
* Create an IPv4 socket for sequenced, reliable, two-way, connection-based
* byte streams.
*
+ * \return The socket fd on success, negative on errors.
+ *
* \sa socket(2).
*/
int get_stream_socket(int domain)
{
- int socket_fd;
+ int fd = socket(domain, SOCK_STREAM, 0);
- if ((socket_fd = socket(domain, SOCK_STREAM, 0)) == -1)
- return -E_SOCKET;
- return socket_fd;
+ if (fd < 0)
+ return -ERRNO_TO_PARA_ERROR(errno);
+ return fd;
}
/**
return new_fd < 0? -ERRNO_TO_PARA_ERROR(errno) : new_fd;
}
-static int setserversockopts(int socket_fd)
-{
- int yes = 1;
-
- if (setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR, &yes,
- sizeof(int)) == -1)
- return -E_SETSOCKOPT;
- return 1;
-}
-
/**
* prepare a structure for \p AF_UNIX socket addresses
*
ret = init_unix_addr(unix_addr, name);
if (ret < 0)
return ret;
- fd = socket(PF_UNIX, SOCK_STREAM, 0);
- if (fd < 0)
- return -E_SOCKET;
- ret = -E_BIND;
- if (bind(fd, (struct sockaddr *) unix_addr, UNIX_PATH_MAX) < 0)
+ ret = socket(PF_UNIX, SOCK_STREAM, 0);
+ if (ret < 0)
+ return -ERRNO_TO_PARA_ERROR(errno);
+ fd = ret;
+ ret = bind(fd, (struct sockaddr *) unix_addr, UNIX_PATH_MAX);
+ if (ret < 0) {
+ ret = -ERRNO_TO_PARA_ERROR(errno);
goto err;
+ }
ret = -E_CHMOD;
if (chmod(name, mode) < 0)
goto err;
* \param buf the buffer to be sent
*
* \return On success, this call returns the number of characters sent. On
- * error, \p -E_SENDMSG ist returned.
+ * error, \p -E_SENDMSG is returned.
*
* \sa okir's Black Hats Manual
* \sa sendmsg(2)
#define BACKLOG 10
/**
- * create a socket, bind it and listen
+ * Create a tcp socket, bind it and listen on the given port.
*
- * \param port the tcp port to listen on
+ * \param port The tcp port to listen on.
*
- * \return The file descriptor of the created socket, negative
- * on errors.
+ * \return The file descriptor of the created socket, negative on errors.
*
* \sa get_stream_socket()
* \sa setsockopt(2)
* \sa bind(2)
* \sa listen(2)
*/
-int init_tcp_socket(int port)
+int tcp_listen(int port)
{
struct sockaddr_in my_addr;
int fd, ret = get_stream_socket(AF_INET);
if (ret < 0)
return ret;
fd = ret;
- ret = setserversockopts(fd);
- if (ret < 0)
+ ret = 1;
+ ret = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &ret, sizeof(int));
+ if (ret < 0) {
+ ret = -ERRNO_TO_PARA_ERROR(errno);
goto err;
+ }
init_sockaddr(&my_addr, port, NULL);
- ret = -E_BIND;
- if (bind(fd, (struct sockaddr *)&my_addr,
- sizeof(struct sockaddr)) == -1) {
- PARA_CRIT_LOG("bind error: %s\n", strerror(errno));
+ ret = bind(fd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr));
+ if (ret < 0) {
+ ret = -ERRNO_TO_PARA_ERROR(errno);
goto err;
}
- ret = -E_LISTEN;
- if (listen(fd, BACKLOG) == -1)
+ ret = listen(fd, BACKLOG);
+ if (ret < 0) {
+ ret = -ERRNO_TO_PARA_ERROR(errno);
goto err;
+ }
PARA_INFO_LOG("listening on port %d, fd %d\n", port, fd);
return fd;
err: