/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Originally developed by Aaron Bannert and Justin Erenkrantz, eBuilt.
 */

#include "config.h"
#include "flood_profile.h"
#include "flood_net.h"

/* Open the TCP connection to the server */
flood_socket_t* open_socket(apr_pool_t *pool, request_t *r,
                            apr_status_t *status)
{
    apr_status_t rv = 0;
    apr_sockaddr_t *destsa;
    flood_socket_t* fs;
    apr_uri_t *u;
    
    fs = apr_palloc(pool, sizeof(flood_socket_t));
    if (r->parsed_proxy_uri) {
        u = r->parsed_proxy_uri;
    }
    else {
        u = r->parsed_uri;
    }

    if ((rv = apr_sockaddr_info_get(&destsa, u->hostname, APR_INET,
                                    u->port, 0, pool)) 
                                    != APR_SUCCESS) {
        if (status) {
            *status = rv;
        }
        return NULL;
    }

    if ((rv = apr_socket_create(&fs->socket, APR_INET, SOCK_STREAM,
                                APR_PROTO_TCP, pool)) != APR_SUCCESS) {
        if (status) {
            *status = rv;
        }
        return NULL;
    }

    if ((rv = apr_socket_connect(fs->socket, destsa)) != APR_SUCCESS) {
        if (APR_STATUS_IS_EINPROGRESS(rv)) {
            /* FIXME: Handle better */
            close_socket(fs);
            if (status) {
                *status = rv;
            }
            return NULL;
        }
        else if (APR_STATUS_IS_EAGAIN(rv))
        {
            /* We have run out of ports available due to TIME_WAIT exhaustion.
             * Sleep for four minutes, and try again. 
             * Note: Solaris returns EADDRNOTAVAIL, Linux returns EAGAIN.
             * XXX: Then APR'IZE THIS ALREADY
             */
            apr_sleep(4 * 60 * APR_USEC_PER_SEC);
            return open_socket(pool, r, status);
        }
        else
        {
            /* FIXME: Handle */
            close_socket(fs);
            if (status) {
                *status = rv;
            }
            return NULL;
        }
    }

    apr_socket_timeout_set(fs->socket, LOCAL_SOCKET_TIMEOUT);
    fs->read_pollset.desc_type = APR_POLL_SOCKET;
    fs->read_pollset.desc.s = fs->socket;
    fs->read_pollset.reqevents = APR_POLLIN;
    fs->read_pollset.p = pool;
    
    return fs;
}

/* close down TCP socket */
void close_socket(flood_socket_t *s)
{
    /* FIXME: recording and other stuff here? */
    apr_socket_close(s->socket);
}

apr_status_t read_socket(flood_socket_t *s, char *buf, apr_size_t *buflen)
{
    apr_status_t e;
    apr_int32_t socketsRead;

    e = apr_poll(&s->read_pollset, 1, &socketsRead, LOCAL_SOCKET_TIMEOUT);
    if (e != APR_SUCCESS)
        return e;
    return apr_socket_recv(s->socket, buf, buflen);
}

apr_status_t write_socket(flood_socket_t *s, request_t *r)
{
    apr_size_t l;
    apr_status_t e;

    l = r->rbufsize;

    e = apr_socket_send(s->socket, r->rbuf, &l);

    /* FIXME: Better error and allow restarts? */
    if (l != r->rbufsize)
        return APR_EGENERAL;

    return e;
}

apr_status_t check_socket(flood_socket_t *s, apr_pool_t *pool)
{
    apr_status_t e;
    apr_int32_t socketsRead;
    apr_pollfd_t pout;
    apr_int16_t event;

    pout.desc_type = APR_POLL_SOCKET;
    pout.desc.s = s->socket;
    pout.reqevents = APR_POLLIN | APR_POLLPRI | APR_POLLERR | APR_POLLHUP | APR_POLLNVAL;
    pout.p = pool;
    
    e = apr_poll(&pout, 1, &socketsRead, 1000);
    if (socketsRead && pout.rtnevents) {
        return APR_EGENERAL;
    }
    
    return APR_SUCCESS;
}
