socket.c 3.32 KB
#include <stdio.h>      /* for printf() and fprintf() */
#include <sys/types.h>  /* SO_REUSEADDR */
#include <sys/socket.h> /* for socket(), bind(), and connect() */
#include <arpa/inet.h>  /* for sockaddr_in and inet_ntoa() */
#include <stdlib.h>     /* for atoi() and exit() */
#include <string.h>     /* for memset() */
#include <unistd.h>     /* for close() */
#include <errno.h>      /* for errno */
#include <syslog.h>

#include "include/appConfig.h"
#include "include/monitor.h"


int
initServerSocket(in_port_t port, int backlog)
{
    int                sock;     /* socket descriptor for server */
    struct sockaddr_in addr;     /* Local address */

    int                reUse = 1;  /* TODO: make this configurable */

    /* Create socket for incoming connections */
    if (-1 == (sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP))) {
        syslogMonitor(LOG_ERR, MON_CRITICAL, "server.socket",
                "error opening socket: %s",
                strerror(errno));
        syslogMonitor(LOG_ERR, MON_FAILURE, "server.socket",
                "error opening socket: %s - service terminated",
                strerror(errno));
        exit(EXIT_FAILURE);
    }

    /* Make the socket REUSE a TIME_WAT socket */
    setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &reUse, sizeof (reUse));

    /* Construct local address structure */
    memset(&addr, 0, sizeof(addr));       /* Zero out structure */

    addr.sin_family      = AF_INET;           /* Internet address family */
    addr.sin_addr.s_addr = htonl(INADDR_ANY); /* Any incoming interface */
    addr.sin_port        = htons(port);       /* Local port */

    /* Bind to the local address */
    if (-1 == bind(sock, (struct sockaddr *) &addr, sizeof(addr))) {
        syslogMonitor(LOG_ERR, MON_CRITICAL, "server.bind",
                "error binding socket: %s",
                strerror(errno));
        syslogMonitor(LOG_ERR, MON_FAILURE, "server.bind",
                "error binding socket: %s - service terminated",
                strerror(errno));
        exit(EXIT_FAILURE);
    }

    /* Mark the socket so it will listen for incoming connections */
    if (-1 == listen(sock, backlog)) {
        syslogMonitor(LOG_ERR, MON_CRITICAL, "server.listen",
                "error binding socket: %s - service terminated",
                strerror(errno));
        syslogMonitor(LOG_ERR, MON_FAILURE, "server.listen",
                "error binding socket: %s - service terminated",
                strerror(errno));
        exit(EXIT_FAILURE);
    }

    return sock;
}

int
acceptConnection(int servSock, char remoteAddr[16])
{
    int                sock;   /* Socket descriptor for client */
    struct sockaddr_in addr;   /* Client address */
    unsigned int       len;    /* Length of client address data structure */

    /* Set the size of the in-out parameter */
    len = sizeof(addr);

    /* Wait for a client to connect */
    if (-1 == (sock = accept(servSock, (struct sockaddr *) &addr, &len))) {
        syslogMonitor(LOG_ERR, MON_WARNING, "server.accept", 
                "error acception connection: %s", strerror(errno));
    } else {
        strncpy (remoteAddr, inet_ntoa(addr.sin_addr), sizeof(remoteAddr)-1);
    }

    /* clntSock is connected to a client! */
    if (0 != verbose) {
        syslog(LOG_INFO, "handling client %s\n", inet_ntoa(addr.sin_addr));
    }

    return sock;
}