/*
 * Functions operating on SOCK_STREAM and buffers.
 *
 * Copyright 2000-2007 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/buffers.h>
#include <types/global.h>
#include <types/polling.h>

#include <proto/client.h>
#include <proto/fd.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;
	int read_poll = MAX_READ_POLL_LOOPS;

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

	if (fdtab[fd].state != FD_STERROR) {
		while (read_poll-- > 0)
		{
			if (b->l == 0) { /* let's realign the buffer to optimize I/O */
				b->r = b->w = 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;

				/* generally if we read something smaller than the 1 or 2 MSS,
				 * it means that it's not worth trying to read again.
				 */
				if (ret < MIN_RET_FOR_READ_LOOP)
					break;
				if (!read_poll)
					break;

				/* 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) */
	}
	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->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:
 */
