/*
 * Functions operating on SOCK_STREAM and buffers.
 *
 * Copyright 2000-2006 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 <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>

#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>

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

#include <types/backend.h>
#include <types/buffers.h>
#include <types/global.h>
#include <types/httperr.h>
#include <types/polling.h>
#include <types/proxy.h>
#include <types/server.h>
#include <types/session.h>

#include <proto/client.h>
#include <proto/fd.h>
#include <proto/log.h>
#include <proto/proto_http.h>
#include <proto/stream_sock.h>
#include <proto/task.h>


/*
 * this function is called on a read event from a stream socket.
 * It returns 0.
 */
int stream_sock_read(int fd) {
	struct buffer *b = fdtab[fd].cb[DIR_RD].b;
	int ret, max;

#ifdef DEBUG_FULL
	fprintf(stderr,"stream_sock_read : fd=%d, owner=%p\n", fd, fdtab[fd].owner);
#endif

	if (fdtab[fd].state != FD_STERROR) {
#ifdef FILL_BUFFERS
		while (1)
#else
		do
#endif
		{
			if (b->l == 0) { /* let's realign the buffer to optimize I/O */
				b->r = b->w = b->h = b->lr  = b->data;
				max = b->rlim - b->data;
			}
			else if (b->r > b->w) {
				max = b->rlim - b->r;
			}
			else {
				max = b->w - b->r;
				/* FIXME: theorically, if w>0, we shouldn't have rlim < data+size anymore
				 * since it means that the rewrite protection has been removed. This
				 * implies that the if statement can be removed.
				 */
				if (max > b->rlim - b->data)
					max = b->rlim - b->data;
			}
	    
			if (max == 0) {  /* not anymore room to store data */
				MY_FD_CLR(fd, StaticReadEvent);
				break;
			}

#ifndef MSG_NOSIGNAL
			{
				int skerr;
				socklen_t lskerr = sizeof(skerr);
	
				ret = getsockopt(fd, SOL_SOCKET, SO_ERROR, &skerr, &lskerr);
				if (ret == -1 || skerr)
					ret = -1;
				else
					ret = recv(fd, b->r, max, 0);
			}
#else
			ret = recv(fd, b->r, max, MSG_NOSIGNAL);
#endif
			if (ret > 0) {
				b->r += ret;
				b->l += ret;
				b->flags |= BF_PARTIAL_READ;
	
				if (b->r == b->data + BUFSIZE) {
					b->r = b->data; /* wrap around the buffer */
				}

				b->total += ret;
				/* we hope to read more data or to get a close on next round */
				continue;
			}
			else if (ret == 0) {
				b->flags |= BF_READ_NULL;
				break;
			}
			else if (errno == EAGAIN) {/* ignore EAGAIN */
				break;
			}
			else {
				b->flags |= BF_READ_ERROR;
				fdtab[fd].state = FD_STERROR;
				break;
			}
		} /* while(1) */
#ifndef FILL_BUFFERS
		while (0);
#endif
	}
	else {
		b->flags |= BF_READ_ERROR;
		fdtab[fd].state = FD_STERROR;
	}

	if (b->flags & BF_READ_STATUS) {
		if (b->rto && MY_FD_ISSET(fd, StaticReadEvent))
			tv_delayfrom(&b->rex, &now, b->rto);
		else
			tv_eternity(&b->rex);
	
		task_wakeup(&rq, fdtab[fd].owner);
	}

	return 0;
}


/*
 * this function is called on a write event from a stream socket.
 * It returns 0.
 */
int stream_sock_write(int fd) {
	struct buffer *b = fdtab[fd].cb[DIR_WR].b;
	int ret, max;

#ifdef DEBUG_FULL
	fprintf(stderr,"stream_sock_write : fd=%d, owner=%p\n", fd, fdtab[fd].owner);
#endif

	if (b->l == 0) { /* let's realign the buffer to optimize I/O */
		b->r = b->w = b->h = b->lr  = b->data;
		max = 0;
	}
	else if (b->r > b->w) {
		max = b->r - b->w;
	}
	else
		max = b->data + BUFSIZE - b->w;
    
	if (fdtab[fd].state != FD_STERROR) {
		if (max == 0) {
			/* may be we have received a connection acknowledgement in TCP mode without data */
			if (fdtab[fd].state == FD_STCONN) {
				int skerr;
				socklen_t lskerr = sizeof(skerr);
				ret = getsockopt(fd, SOL_SOCKET, SO_ERROR, &skerr, &lskerr);
				if (ret == -1 || skerr) {
					b->flags |= BF_WRITE_ERROR;
					fdtab[fd].state = FD_STERROR;
					task_wakeup(&rq, fdtab[fd].owner);
					tv_eternity(&b->wex);
					MY_FD_CLR(fd, StaticWriteEvent);
					return 0;
				}
			}

			b->flags |= BF_WRITE_NULL;
			task_wakeup(&rq, fdtab[fd].owner);
			fdtab[fd].state = FD_STREADY;
			tv_eternity(&b->wex);
			MY_FD_CLR(fd, StaticWriteEvent);
			return 0;
		}

#ifndef MSG_NOSIGNAL
		{
			int skerr;
			socklen_t lskerr = sizeof(skerr);

			ret = getsockopt(fd, SOL_SOCKET, SO_ERROR, &skerr, &lskerr);
			if (ret == -1 || skerr)
				ret = -1;
			else
				ret = send(fd, b->w, max, MSG_DONTWAIT);
		}
#else
		ret = send(fd, b->w, max, MSG_DONTWAIT | MSG_NOSIGNAL);
#endif

		if (ret > 0) {
			b->l -= ret;
			b->w += ret;
	    
			b->flags |= BF_PARTIAL_WRITE;
	    
			if (b->w == b->data + BUFSIZE) {
				b->w = b->data; /* wrap around the buffer */
			}
		}
		else if (ret == 0) {
			/* nothing written, just pretend we were never called */
			// b->flags |= BF_WRITE_NULL;
			return 0;
		}
		else if (errno == EAGAIN) /* ignore EAGAIN */
			return 0;
		else {
			b->flags |= BF_WRITE_ERROR;
			fdtab[fd].state = FD_STERROR;
		}
	}
	else {
		b->flags |= BF_WRITE_ERROR;
		fdtab[fd].state = FD_STERROR;
	}

	if (b->wto) {
		tv_delayfrom(&b->wex, &now, b->wto);
		/* FIXME: to prevent the client from expiring read timeouts during writes,
		 * we refresh it. A solution would be to merge read+write timeouts into a
		 * unique one, although that needs some study particularly on full-duplex
		 * TCP connections. */
		b->rex = b->wex;
	}
	else
		tv_eternity(&b->wex);

	task_wakeup(&rq, fdtab[fd].owner);
	return 0;
}



/*
 * Local variables:
 *  c-indent-level: 8
 *  c-basic-offset: 8
 * End:
 */
