/* incoming call handling
 *
 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
 * Written by David Howells (dhowells@redhat.com)
 *
 * 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 <linux/module.h>
#include <linux/net.h>
#include <linux/skbuff.h>
#include <linux/errqueue.h>
#include <linux/udp.h>
#include <linux/in.h>
#include <linux/in6.h>
#include <linux/icmp.h>
#include <net/sock.h>
#include <net/af_rxrpc.h>
#include <net/ip.h>
#include "ar-internal.h"

/*
 * generate a connection-level abort
 */
static int rxrpc_busy(struct rxrpc_local *local, struct sockaddr_rxrpc *srx,
		      struct rxrpc_header *hdr)
{
	struct msghdr msg;
	struct kvec iov[1];
	size_t len;
	int ret;

	_enter("%d,,", local->debug_id);

	msg.msg_name	= &srx->transport.sin;
	msg.msg_namelen	= sizeof(srx->transport.sin);
	msg.msg_control	= NULL;
	msg.msg_controllen = 0;
	msg.msg_flags	= 0;

	hdr->seq	= 0;
	hdr->type	= RXRPC_PACKET_TYPE_BUSY;
	hdr->flags	= 0;
	hdr->userStatus	= 0;
	hdr->_rsvd	= 0;

	iov[0].iov_base	= hdr;
	iov[0].iov_len	= sizeof(*hdr);

	len = iov[0].iov_len;

	hdr->serial = htonl(1);
	_proto("Tx BUSY %%%u", ntohl(hdr->serial));

	ret = kernel_sendmsg(local->socket, &msg, iov, 1, len);
	if (ret < 0) {
		_leave(" = -EAGAIN [sendmsg failed: %d]", ret);
		return -EAGAIN;
	}

	_leave(" = 0");
	return 0;
}

/*
 * accept an incoming call that needs peer, transport and/or connection setting
 * up
 */
static int rxrpc_accept_incoming_call(struct rxrpc_local *local,
				      struct rxrpc_sock *rx,
				      struct sk_buff *skb,
				      struct sockaddr_rxrpc *srx)
{
	struct rxrpc_connection *conn;
	struct rxrpc_transport *trans;
	struct rxrpc_skb_priv *sp, *nsp;
	struct rxrpc_peer *peer;
	struct rxrpc_call *call;
	struct sk_buff *notification;
	int ret;

	_enter("");

	sp = rxrpc_skb(skb);

	/* get a notification message to send to the server app */
	notification = alloc_skb(0, GFP_NOFS);
	rxrpc_new_skb(notification);
	notification->mark = RXRPC_SKB_MARK_NEW_CALL;

	peer = rxrpc_get_peer(srx, GFP_NOIO);
	if (IS_ERR(peer)) {
		_debug("no peer");
		ret = -EBUSY;
		goto error;
	}

	trans = rxrpc_get_transport(local, peer, GFP_NOIO);
	rxrpc_put_peer(peer);
	if (!trans) {
		_debug("no trans");
		ret = -EBUSY;
		goto error;
	}

	conn = rxrpc_incoming_connection(trans, &sp->hdr, GFP_NOIO);
	rxrpc_put_transport(trans);
	if (IS_ERR(conn)) {
		_debug("no conn");
		ret = PTR_ERR(conn);
		goto error;
	}

	call = rxrpc_incoming_call(rx, conn, &sp->hdr, GFP_NOIO);
	rxrpc_put_connection(conn);
	if (IS_ERR(call)) {
		_debug("no call");
		ret = PTR_ERR(call);
		goto error;
	}

	/* attach the call to the socket */
	read_lock_bh(&local->services_lock);
	if (rx->sk.sk_state == RXRPC_CLOSE)
		goto invalid_service;

	write_lock(&rx->call_lock);
	if (!test_and_set_bit(RXRPC_CALL_INIT_ACCEPT, &call->flags)) {
		rxrpc_get_call(call);

		spin_lock(&call->conn->state_lock);
		if (sp->hdr.securityIndex > 0 &&
		    call->conn->state == RXRPC_CONN_SERVER_UNSECURED) {
			_debug("await conn sec");
			list_add_tail(&call->accept_link, &rx->secureq);
			call->conn->state = RXRPC_CONN_SERVER_CHALLENGING;
			atomic_inc(&call->conn->usage);
			set_bit(RXRPC_CONN_CHALLENGE, &call->conn->events);
			rxrpc_queue_conn(call->conn);
		} else {
			_debug("conn ready");
			call->state = RXRPC_CALL_SERVER_ACCEPTING;
			list_add_tail(&call->accept_link, &rx->acceptq);
			rxrpc_get_call(call);
			nsp = rxrpc_skb(notification);
			nsp->call = call;

			ASSERTCMP(atomic_read(&call->usage), >=, 3);

			_debug("notify");
			spin_lock(&call->lock);
			ret = rxrpc_queue_rcv_skb(call, notification, true,
						  false);
			spin_unlock(&call->lock);
			notification = NULL;
			if (ret < 0)
				BUG();
		}
		spin_unlock(&call->conn->state_lock);

		_debug("queued");
	}
	write_unlock(&rx->call_lock);

	_debug("process");
	rxrpc_fast_process_packet(call, skb);

	_debug("done");
	read_unlock_bh(&local->services_lock);
	rxrpc_free_skb(notification);
	rxrpc_put_call(call);
	_leave(" = 0");
	return 0;

invalid_service:
	_debug("invalid");
	read_unlock_bh(&local->services_lock);

	read_lock_bh(&call->state_lock);
	if (!test_bit(RXRPC_CALL_RELEASE, &call->flags) &&
	    !test_and_set_bit(RXRPC_CALL_RELEASE, &call->events)) {
		rxrpc_get_call(call);
		rxrpc_queue_call(call);
	}
	read_unlock_bh(&call->state_lock);
	rxrpc_put_call(call);
	ret = -ECONNREFUSED;
error:
	rxrpc_free_skb(notification);
	_leave(" = %d", ret);
	return ret;
}

/*
 * accept incoming calls that need peer, transport and/or connection setting up
 * - the packets we get are all incoming client DATA packets that have seq == 1
 */
void rxrpc_accept_incoming_calls(struct work_struct *work)
{
	struct rxrpc_local *local =
		container_of(work, struct rxrpc_local, acceptor);
	struct rxrpc_skb_priv *sp;
	struct sockaddr_rxrpc srx;
	struct rxrpc_sock *rx;
	struct sk_buff *skb;
	__be16 service_id;
	int ret;

	_enter("%d", local->debug_id);

	read_lock_bh(&rxrpc_local_lock);
	if (atomic_read(&local->usage) > 0)
		rxrpc_get_local(local);
	else
		local = NULL;
	read_unlock_bh(&rxrpc_local_lock);
	if (!local) {
		_leave(" [local dead]");
		return;
	}

process_next_packet:
	skb = skb_dequeue(&local->accept_queue);
	if (!skb) {
		rxrpc_put_local(local);
		_leave("\n");
		return;
	}

	_net("incoming call skb %p", skb);

	sp = rxrpc_skb(skb);

	/* determine the remote address */
	memset(&srx, 0, sizeof(srx));
	srx.srx_family = AF_RXRPC;
	srx.transport.family = local->srx.transport.family;
	srx.transport_type = local->srx.transport_type;
	switch (srx.transport.family) {
	case AF_INET:
		srx.transport_len = sizeof(struct sockaddr_in);
		srx.transport.sin.sin_port = udp_hdr(skb)->source;
		srx.transport.sin.sin_addr.s_addr = ip_hdr(skb)->saddr;
		break;
	default:
		goto busy;
	}

	/* get the socket providing the service */
	service_id = sp->hdr.serviceId;
	read_lock_bh(&local->services_lock);
	list_for_each_entry(rx, &local->services, listen_link) {
		if (rx->service_id == service_id &&
		    rx->sk.sk_state != RXRPC_CLOSE)
			goto found_service;
	}
	read_unlock_bh(&local->services_lock);
	goto invalid_service;

found_service:
	_debug("found service %hd", ntohs(rx->service_id));
	if (sk_acceptq_is_full(&rx->sk))
		goto backlog_full;
	sk_acceptq_added(&rx->sk);
	sock_hold(&rx->sk);
	read_unlock_bh(&local->services_lock);

	ret = rxrpc_accept_incoming_call(local, rx, skb, &srx);
	if (ret < 0)
		sk_acceptq_removed(&rx->sk);
	sock_put(&rx->sk);
	switch (ret) {
	case -ECONNRESET: /* old calls are ignored */
	case -ECONNABORTED: /* aborted calls are reaborted or ignored */
	case 0:
		goto process_next_packet;
	case -ECONNREFUSED:
		goto invalid_service;
	case -EBUSY:
		goto busy;
	case -EKEYREJECTED:
		goto security_mismatch;
	default:
		BUG();
	}

backlog_full:
	read_unlock_bh(&local->services_lock);
busy:
	rxrpc_busy(local, &srx, &sp->hdr);
	rxrpc_free_skb(skb);
	goto process_next_packet;

invalid_service:
	skb->priority = RX_INVALID_OPERATION;
	rxrpc_reject_packet(local, skb);
	goto process_next_packet;

	/* can't change connection security type mid-flow */
security_mismatch:
	skb->priority = RX_PROTOCOL_ERROR;
	rxrpc_reject_packet(local, skb);
	goto process_next_packet;
}

/*
 * handle acceptance of a call by userspace
 * - assign the user call ID to the call at the front of the queue
 */
struct rxrpc_call *rxrpc_accept_call(struct rxrpc_sock *rx,
				     unsigned long user_call_ID)
{
	struct rxrpc_call *call;
	struct rb_node *parent, **pp;
	int ret;

	_enter(",%lx", user_call_ID);

	ASSERT(!irqs_disabled());

	write_lock(&rx->call_lock);

	ret = -ENODATA;
	if (list_empty(&rx->acceptq))
		goto out;

	/* check the user ID isn't already in use */
	ret = -EBADSLT;
	pp = &rx->calls.rb_node;
	parent = NULL;
	while (*pp) {
		parent = *pp;
		call = rb_entry(parent, struct rxrpc_call, sock_node);

		if (user_call_ID < call->user_call_ID)
			pp = &(*pp)->rb_left;
		else if (user_call_ID > call->user_call_ID)
			pp = &(*pp)->rb_right;
		else
			goto out;
	}

	/* dequeue the first call and check it's still valid */
	call = list_entry(rx->acceptq.next, struct rxrpc_call, accept_link);
	list_del_init(&call->accept_link);
	sk_acceptq_removed(&rx->sk);

	write_lock_bh(&call->state_lock);
	switch (call->state) {
	case RXRPC_CALL_SERVER_ACCEPTING:
		call->state = RXRPC_CALL_SERVER_RECV_REQUEST;
		break;
	case RXRPC_CALL_REMOTELY_ABORTED:
	case RXRPC_CALL_LOCALLY_ABORTED:
		ret = -ECONNABORTED;
		goto out_release;
	case RXRPC_CALL_NETWORK_ERROR:
		ret = call->conn->error;
		goto out_release;
	case RXRPC_CALL_DEAD:
		ret = -ETIME;
		goto out_discard;
	default:
		BUG();
	}

	/* formalise the acceptance */
	call->user_call_ID = user_call_ID;
	rb_link_node(&call->sock_node, parent, pp);
	rb_insert_color(&call->sock_node, &rx->calls);
	if (test_and_set_bit(RXRPC_CALL_HAS_USERID, &call->flags))
		BUG();
	if (test_and_set_bit(RXRPC_CALL_ACCEPTED, &call->events))
		BUG();
	rxrpc_queue_call(call);

	rxrpc_get_call(call);
	write_unlock_bh(&call->state_lock);
	write_unlock(&rx->call_lock);
	_leave(" = %p{%d}", call, call->debug_id);
	return call;

	/* if the call is already dying or dead, then we leave the socket's ref
	 * on it to be released by rxrpc_dead_call_expired() as induced by
	 * rxrpc_release_call() */
out_release:
	_debug("release %p", call);
	if (!test_bit(RXRPC_CALL_RELEASED, &call->flags) &&
	    !test_and_set_bit(RXRPC_CALL_RELEASE, &call->events))
		rxrpc_queue_call(call);
out_discard:
	write_unlock_bh(&call->state_lock);
	_debug("discard %p", call);
out:
	write_unlock(&rx->call_lock);
	_leave(" = %d", ret);
	return ERR_PTR(ret);
}

/*
 * handle rejectance of a call by userspace
 * - reject the call at the front of the queue
 */
int rxrpc_reject_call(struct rxrpc_sock *rx)
{
	struct rxrpc_call *call;
	int ret;

	_enter("");

	ASSERT(!irqs_disabled());

	write_lock(&rx->call_lock);

	ret = -ENODATA;
	if (list_empty(&rx->acceptq))
		goto out;

	/* dequeue the first call and check it's still valid */
	call = list_entry(rx->acceptq.next, struct rxrpc_call, accept_link);
	list_del_init(&call->accept_link);
	sk_acceptq_removed(&rx->sk);

	write_lock_bh(&call->state_lock);
	switch (call->state) {
	case RXRPC_CALL_SERVER_ACCEPTING:
		call->state = RXRPC_CALL_SERVER_BUSY;
		if (test_and_set_bit(RXRPC_CALL_REJECT_BUSY, &call->events))
			rxrpc_queue_call(call);
		ret = 0;
		goto out_release;
	case RXRPC_CALL_REMOTELY_ABORTED:
	case RXRPC_CALL_LOCALLY_ABORTED:
		ret = -ECONNABORTED;
		goto out_release;
	case RXRPC_CALL_NETWORK_ERROR:
		ret = call->conn->error;
		goto out_release;
	case RXRPC_CALL_DEAD:
		ret = -ETIME;
		goto out_discard;
	default:
		BUG();
	}

	/* if the call is already dying or dead, then we leave the socket's ref
	 * on it to be released by rxrpc_dead_call_expired() as induced by
	 * rxrpc_release_call() */
out_release:
	_debug("release %p", call);
	if (!test_bit(RXRPC_CALL_RELEASED, &call->flags) &&
	    !test_and_set_bit(RXRPC_CALL_RELEASE, &call->events))
		rxrpc_queue_call(call);
out_discard:
	write_unlock_bh(&call->state_lock);
	_debug("discard %p", call);
out:
	write_unlock(&rx->call_lock);
	_leave(" = %d", ret);
	return ret;
}

/**
 * rxrpc_kernel_accept_call - Allow a kernel service to accept an incoming call
 * @sock: The socket on which the impending call is waiting
 * @user_call_ID: The tag to attach to the call
 *
 * Allow a kernel service to accept an incoming call, assuming the incoming
 * call is still valid.
 */
struct rxrpc_call *rxrpc_kernel_accept_call(struct socket *sock,
					    unsigned long user_call_ID)
{
	struct rxrpc_call *call;

	_enter(",%lx", user_call_ID);
	call = rxrpc_accept_call(rxrpc_sk(sock->sk), user_call_ID);
	_leave(" = %p", call);
	return call;
}

EXPORT_SYMBOL(rxrpc_kernel_accept_call);

/**
 * rxrpc_kernel_reject_call - Allow a kernel service to reject an incoming call
 * @sock: The socket on which the impending call is waiting
 *
 * Allow a kernel service to reject an incoming call with a BUSY message,
 * assuming the incoming call is still valid.
 */
int rxrpc_kernel_reject_call(struct socket *sock)
{
	int ret;

	_enter("");
	ret = rxrpc_reject_call(rxrpc_sk(sock->sk));
	_leave(" = %d", ret);
	return ret;
}

EXPORT_SYMBOL(rxrpc_kernel_reject_call);
