/*
 * Connection management functions
 *
 * Copyright 2000-2012 Willy Tarreau <w@1wt.eu>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version
 * 2 of the License, or (at your option) any later version.
 *
 */

#include <common/compat.h>
#include <common/config.h>

#include <types/connection.h>

#include <proto/proto_tcp.h>
#include <proto/stream_interface.h>

/* I/O callback for fd-based connections. It calls the read/write handlers
 * provided by the connection's sock_ops, which must be valid. It returns
 * FD_WAIT_*.
 */
int conn_fd_handler(int fd)
{
	struct connection *conn = fdtab[fd].owner;
	int ret = 0;

	if (!conn)
		goto leave;

	if (conn->flags & CO_FL_ERROR)
		goto leave;

	if (conn->flags & CO_FL_SI_SEND_PROXY)
		if ((ret = conn_si_send_proxy(conn, CO_FL_SI_SEND_PROXY)))
			goto leave;

	if (fdtab[fd].ev & (FD_POLL_IN | FD_POLL_HUP | FD_POLL_ERR))
		if (!conn->data->read(conn))
			ret |= FD_WAIT_READ;

	if (conn->flags & CO_FL_ERROR)
		goto leave;

	if (fdtab[fd].ev & (FD_POLL_OUT | FD_POLL_ERR))
		if (!conn->data->write(conn))
			ret |= FD_WAIT_WRITE;

	if (conn->flags & CO_FL_ERROR)
		goto leave;

	if (conn->flags & CO_FL_WAIT_L4_CONN) {
		/* still waiting for a connection to establish and no data to
		 * send in order to probe it ? Then let's retry the connect().
		 */
		if (!tcp_connect_probe(conn))
			ret |= FD_WAIT_WRITE;
	}

 leave:
	if (conn->flags & CO_FL_NOTIFY_SI)
		stream_sock_update_conn(conn);

	/* Last check, verify if the connection just established */
	if (!(conn->flags & (CO_FL_WAIT_L4_CONN | CO_FL_CONNECTED)))
		conn->flags |= CO_FL_CONNECTED;

	/* remove the events before leaving */
	fdtab[fd].ev &= ~(FD_POLL_IN | FD_POLL_OUT | FD_POLL_HUP | FD_POLL_ERR);
	return ret;
}
