/*-
 * Copyright (c) 1982, 1986, 1988, 1993
 *	The Regents of the University of California.
 * Copyright (c) 2006-2007 Robert N. M. Watson
 * Copyright (c) 2010-2011 Juniper Networks, Inc.
 * All rights reserved.
 *
 * Portions of this software were developed by Robert N. M. Watson under
 * contract to Juniper Networks, Inc.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 *	From: @(#)tcp_usrreq.c	8.2 (Berkeley) 1/3/94
 */

#include <errno.h>
#include <string.h>
#include "../tcplp.h"
#include "../lib/cbuf.h"
#include "tcp.h"
#include "tcp_fsm.h"
#include "tcp_seq.h"
#include "tcp_var.h"
#include "tcp_timer.h"
//#include <sys/socket.h>
#include "ip6.h"

#include "tcp_const.h"

#include <openthread/tcp.h>

//static void	tcp_disconnect(struct tcpcb *);
static void	tcp_usrclosed(struct tcpcb *);

/*
 * samkumar: Removed tcp6_usr_bind, since checking if an address/port is free
 * needs to be done at the host system (along with other socket management
 * duties). TCPlp doesn't know what other sockets are in the system, or which
 * other addresses/ports are busy.
 */

/* samkumar: This is based on a function in in6_pcb.c. */
static int in6_pcbconnect(struct tcpcb* tp, struct sockaddr_in6* nam) {
	register struct sockaddr_in6 *sin6 = nam;
	tp->faddr = sin6->sin6_addr;
	tp->fport = sin6->sin6_port;
	return 0;
}

/*
 * Initiate connection to peer.
 * Create a template for use in transmissions on this connection.
 * Enter SYN_SENT state, and mark socket as connecting.
 * Start keep-alive timer, and seed output sequence space.
 * Send initial segment on connection.
 */
/*
 * samkumar: I removed locking, statistics, and inpcb management. The signature
 * used to be
 *
 * static int
 * tcp6_connect(struct tcpcb *tp, struct sockaddr *nam, struct thread *td)
 */
static int
tcp6_connect(struct tcpcb *tp, struct sockaddr_in6 *nam)
{
	int error;

	int sb_max = cbuf_free_space(&tp->recvbuf); // same as sendbuf

	/*
	 * samkumar: For autobind, the original BSD code assigned the port first
	 * (with logic that also looked at the address) and then the address. This
	 * was done by calling into other parts of the FreeBSD network stack,
	 * outside of the TCP stack. Here, we just use the tcplp_sys_autobind
	 * function to do all of that work.
	 */
	bool autobind_addr = IN6_IS_ADDR_UNSPECIFIED(&tp->laddr);
	bool autobind_port = (tp->lport == 0);
	if (autobind_addr || autobind_port) {
		otSockAddr foreign;
		otSockAddr local;

		memcpy(&foreign.mAddress, &nam->sin6_addr, sizeof(foreign.mAddress));
		foreign.mPort = ntohs(nam->sin6_port);

		if (!autobind_addr) {
			memcpy(&local.mAddress, &tp->laddr, sizeof(local.mAddress));
		}

		if (!autobind_port) {
			local.mPort = ntohs(tp->lport);
		}

		if (!tcplp_sys_autobind(tp->instance, &foreign, &local, autobind_addr, autobind_port)) {
			// Autobind failed
			error = EINVAL;
			goto out;
		}

		if (autobind_addr) {
			memcpy(&tp->laddr, &local.mAddress, sizeof(tp->laddr));
		}

		if (autobind_port) {
			tp->lport = htons(local.mPort);
		}
	}
	error = in6_pcbconnect(tp, nam);
	if (error != 0)
		goto out;

	/* Compute window scaling to request.  */
	while (tp->request_r_scale < TCP_MAX_WINSHIFT &&
	    (TCP_MAXWIN << tp->request_r_scale) < sb_max)
		tp->request_r_scale++;

	tcp_state_change(tp, TCPS_SYN_SENT);
	tp->iss = tcp_new_isn(tp);
	tcp_sendseqinit(tp);

	return 0;

out:
	return error;
}

/*
 * samkumar: I removed locking, statistics, inpcb management, and debug probes.
 * I also remove codepaths that check for IPv6, since the address is assumed to
 * be IPv6. The signature used to be
 *
 * static int
 * tcp6_usr_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
 */
int
tcp6_usr_connect(struct tcpcb* tp, struct sockaddr_in6* sin6p)
{
	int error = 0;

	if (tp->t_state != TCPS_CLOSED) { // samkumar: This is a check that I added
		return (EISCONN);
	}

	/* samkumar: I removed the following error check since we receive sin6p
	 * in the function argument and don't need to convert a struct sockaddr to
	 * a struct sockaddr_in6 anymore.
	 *
	 * if (nam->sa_len != sizeof (*sin6p))
	 * 	return (EINVAL);
	 */

	/*
	 * Must disallow TCP ``connections'' to multicast addresses.
	 */
	/* samkumar: I commented out the check on sin6p->sin6_family. */
	if (/*sin6p->sin6_family == AF_INET6
	    && */IN6_IS_ADDR_MULTICAST(&sin6p->sin6_addr))
		return (EAFNOSUPPORT);

	/*
	 * samkumar: There was some code here that obtained the TCB (struct tcpcb*)
	 * by getting the inpcb from the socket and the TCB from the inpcb. I
	 * removed that code.
	 */

	/*
	 * XXXRW: Some confusion: V4/V6 flags relate to binding, and
	 * therefore probably require the hash lock, which isn't held here.
	 * Is this a significant problem?
	 */
	if (IN6_IS_ADDR_V4MAPPED(&sin6p->sin6_addr)) {
		tcplp_sys_log("V4-Mapped Address!");

		/*
		 * samkumar: There used to be code that woulf handle the case of
		 * v4-mapped addresses. It would call in6_sin6_2_sin to convert the
		 * struct sockaddr_in6 to a struct sockaddr_in, set the INP_IPV4 flag
		 * and clear the INP_IPV6 flag on inp->inp_vflag, do some other
		 * processing, and finally call tcp_connect and tcp_output. However,
		 * it would first check if the IN6P_IPV6_V6ONLY flag was set in
		 * inp->inp_flags, and if so, it would return with EINVAL. In TCPlp, we
		 * support IPv6 only, so I removed the check for IN6P_IPV6_V6ONLY and
		 * always act as if that flag is set. I kept the code in that if
		 * statement making the check, and removed the other code that actually
		 * handled this case.
		 */
		error = EINVAL;
		goto out;
	}

	/*
	 * samkumar: I removed some code here that set/cleared some flags in the`
	 * inpcb and called prison_remote_ip6.
	 */

	/*
	 * samkumar: Originally, the struct thread *td was passed along to
	 * tcp6_connect.
	 */
	if ((error = tcp6_connect(tp, sin6p)) != 0)
		goto out;

	tcp_timer_activate(tp, TT_KEEP, TP_KEEPINIT(tp));
	error = tcp_output(tp);

out:
	return (error);
}

/*
 * Do a send by putting data in output queue and updating urgent
 * marker if URG set.  Possibly send more data.  Unlike the other
 * pru_*() routines, the mbuf chains are our responsibility.  We
 * must either enqueue them or free them.  The other pru_* routines
 * generally are caller-frees.
 */
/*
 * samkumar: I removed locking, statistics, inpcb management, and debug probes.
 * I also removed support for the urgent pointer.
 *
 * I changed the signature of this function. It used to be
 * static int
 * tcp_usr_send(struct socket *so, int flags, struct mbuf *m,
 *     struct sockaddr *nam, struct mbuf *control, struct thread *td)
 *
 * The new function signature works as follows. DATA is a new linked buffer to
 * add to the end of the send buffer. EXTENDBY is the number of bytes by which
 * to extend the final linked buffer of the send buffer. Either DATA should be
 * NULL, or EXTENDBY should be 0.
 */
int tcp_usr_send(struct tcpcb* tp, int moretocome, otLinkedBuffer* data, size_t extendby)
{
	int error = 0;

	/*
	 * samkumar: This if statement and the next are checks that I added
	 */
	if (tp->t_state < TCPS_ESTABLISHED) {
		error = ENOTCONN;
		goto out;
	}

	if (tpiscantsend(tp)) {
		error = EPIPE;
		goto out;
	}

	/*
	 * samkumar: There used to be logic here that acquired locks, dealt with
	 * INP_TIMEWAIT and INP_DROPPED flags on inp->inp_flags, and handled the
	 * control mbuf passed as an argument (which would result in an error since
	 * TCP doesn't support control information). I've deleted that code, but
	 * left the following if block.
	 */
	 if ((tp->t_state == TCPS_TIME_WAIT) || (tp->t_state == TCPS_CLOSED)) {
		error = ECONNRESET;
		goto out;
	}

	/*
	 * The following code used to be wrapped in an if statement:
	 * "if (!(flags & PRUS_OOB))", that only executed it if the "out of band"
	 * flag was not set. In TCB, "out of band" data is conveyed via the urgent
	 * pointer, and TCPlp does not support the urgent pointer. Therefore, I
	 * removed the "if" check and put its body below.
	 */

	/*
	 * samkumar; The FreeBSD code calls sbappendstream(&so->so_snd, m, flags);
	 * I've replaced it with the following logic, which appends to the
	 * send buffer according to TCPlp's data structures.
	 */
	if (data == NULL) {
		if (extendby == 0) {
			goto out;
		}
		lbuf_extend(&tp->sendbuf, extendby);
	} else {
		if (data->mLength == 0) {
			goto out;
		}
		lbuf_append(&tp->sendbuf, data);
	}

	/*
	 * samkumar: There used to be code here to handle "implied connect,"
	 * which initiates the TCP handshake if sending data on a socket that
	 * isn't yet connected. TCPlp doesn't support this at the moment, but
	 * it might be worth revisiting  when implementing TCP Fast Open.
	 */

	/*
	 * samkumar: There used to be code here handling the PRUS_EOF flag in
	 * the former flags parameter. I've removed this code.
	 */

	/*
	 * samkumar: The code below was previously wrapped in an if statement
	 * that checked that the INP_DROPPED flag in inp->inp_flags and the
	 * PRUS_NOTREADY flag in the former flags parameter were both clear.
	 * If either one was set, then tcp_output would not be called.
	 *
	 * The "more to come" functionality was previously triggered via the
	 * PRUS_MORETOCOME flag in the flags parameter to this function. Since
	 * that's the only flag that TCPlp uses here, I replaced the flags
	 * parameter with a "moretocome" parameter, which we check instead.
	 */
	if (moretocome)
		tp->t_flags |= TF_MORETOCOME;
	error = tcp_output(tp);
	if (moretocome)
		tp->t_flags &= ~TF_MORETOCOME;

	/*
	 * samkumar: This is where the "if (!(flags & PRUS_OOB))" block would end.
	 * There used to be a large "else" block handling out-of-band data, but I
	 * removed that entire block since we do not support the urgent pointer in
	 * TCPlp.
	 */
out:
	return (error);
}

/*
 * After a receive, possibly send window update to peer.
 */
int
tcp_usr_rcvd(struct tcpcb* tp)
{
	int error = 0;

	/*
	 * samkumar: There used to be logic here that acquired locks, dealt with
	 * INP_TIMEWAIT and INP_DROPPED flags on inp->inp_flags, and added debug
	 * probes I've deleted that code, but left the following if block.
	 */
	if ((tp->t_state == TCPS_TIME_WAIT) || (tp->t_state == TCPS_CLOSED)) {
		error = ECONNRESET;
		goto out;
	}

	tcp_output(tp);

out:
	return (error);
}

/*
 * samkumar: Removed the tcp_disconnect function. It is meant to be a
 * "friendly" disconnect to complement the unceremonious "abort" functionality
 * that is also provbided. The FreeBSD implementation called it from
 * tcp_usr_close, which we removed (see the comment below for the reason why).
 * It's not called from anywhere else, so I'm removing this function entirely.
 */

/*
 * Mark the connection as being incapable of further output.
 */
/*
 * samkumar: Modified to remove locking, socket/inpcb handling, and debug
 * probes.
 */
int
tcp_usr_shutdown(struct tcpcb* tp)
{
	int error = 0;

	/*
	 * samkumar: replaced checks on the INP_TIMEWAIT and INP_DROPPED flags on
	 * inp->inp_flags with these checks on tp->t_state.
	 */
	if ((tp->t_state == TCPS_TIME_WAIT) || (tp->t_state == TCPS_CLOSED)) {
		error = ECONNRESET;
		goto out;
	}

	/* samkumar: replaced socantsendmore with tpcantsendmore */
	tpcantsendmore(tp);
	tcp_usrclosed(tp);

	/*
	 * samkumar: replaced check on INP_DROPPED flag in inp->inp_flags with
	 * this check on tp->t_state.
	 */
	if (tp->t_state != TCPS_CLOSED)
		error = tcp_output(tp);

out:
	return (error);
}


/*
 * User issued close, and wish to trail through shutdown states:
 * if never received SYN, just forget it.  If got a SYN from peer,
 * but haven't sent FIN, then go to FIN_WAIT_1 state to send peer a FIN.
 * If already got a FIN from peer, then almost done; go to LAST_ACK
 * state.  In all other cases, have already sent FIN to peer (e.g.
 * after PRU_SHUTDOWN), and just have to play tedious game waiting
 * for peer to send FIN or not respond to keep-alives, etc.
 * We can let the user exit from the close as soon as the FIN is acked.
 */
/*
 * Removed locking, TCP Offload, and socket/inpcb handling.
 */
static void
tcp_usrclosed(struct tcpcb *tp)
{
	switch (tp->t_state) {
	case TCPS_LISTEN:
		tcp_state_change(tp, TCPS_CLOSED);
		/* FALLTHROUGH */
	case TCPS_CLOSED:
		tp = tcp_close(tp);
		tcplp_sys_connection_lost(tp, CONN_LOST_NORMAL);
		/*
		 * tcp_close() should never return NULL here as the socket is
		 * still open.
		 */
		KASSERT(tp != NULL,
		    ("tcp_usrclosed: tcp_close() returned NULL"));
		break;

	case TCPS_SYN_SENT:
	case TCPS_SYN_RECEIVED:
		tp->t_flags |= TF_NEEDFIN;
		break;

	case TCPS_ESTABLISHED:
		tcp_state_change(tp, TCPS_FIN_WAIT_1);
		break;

	case TCPS_CLOSE_WAIT:
		tcp_state_change(tp, TCPS_LAST_ACK);
		break;
	}
	if (tp->t_state >= TCPS_FIN_WAIT_2) {
		/* samkumar: commented out the following "soisdisconnected" line. */
		// soisdisconnected(tp->t_inpcb->inp_socket);
		/* Prevent the connection hanging in FIN_WAIT_2 forever. */
		if (tp->t_state == TCPS_FIN_WAIT_2) {
			int timeout;

			timeout = (tcp_fast_finwait2_recycle) ?
			    tcp_finwait2_timeout : TP_MAXIDLE(tp);
			tcp_timer_activate(tp, TT_2MSL, timeout);
		}
	}
}

/*
 * samkumar: I removed the tcp_usr_close function. It was meant to be called in
 * case the socket is closed. It calls tcp_disconnect if the underlying TCP
 * connection is still alive when the socket is closed ("full TCP state").
 * In TCPlp, we can't handle this because we want to free up the underlying
 * memory immediately when the user deallocates a TCP connection, making it
 * unavailable for the somewhat more ceremonious closing that tcp_disconnect
 * would allow. The host system is expected to simply abort the connection if
 * the application deallocates it.
 */

/*
 * Abort the TCP.  Drop the connection abruptly.
 */
/*
 * samkumar: Modified to remove locking, socket/inpcb handling, and debug
 * probes.
 */
void
tcp_usr_abort(struct tcpcb* tp)
{
	/*
	 * If we still have full TCP state, and we're not dropped, drop.
	 */
	/*
	 * I replaced the checks on inp->inp_flags (which tested for the absence of
	 * INP_TIMEWAIT and INP_DROPPED flags), with the following checks on
	 * tp->t_state.
	 */
	if (tp->t_state != TCP6S_TIME_WAIT &&
		tp->t_state != TCP6S_CLOSED) {
		tcp_drop(tp, ECONNABORTED);
	} else if (tp->t_state == TCPS_TIME_WAIT) { // samkumar: I added this clause
		tp = tcp_close(tp);
		tcplp_sys_connection_lost(tp, CONN_LOST_NORMAL);
	}
}
