/*
 * linux/fs/9p/trans_socket.c
 *
 * Socket Transport Layer
 *
 *  Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
 *  Copyright (C) 1997-2002 by Ron Minnich <rminnich@sarnoff.com>
 *  Copyright (C) 1995, 1996 by Olaf Kirch <okir@monad.swb.de>
 *
 *  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.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to:
 *  Free Software Foundation
 *  51 Franklin Street, Fifth Floor
 *  Boston, MA  02111-1301  USA
 *
 */

#include <linux/config.h>
#include <linux/in.h>
#include <linux/module.h>
#include <linux/net.h>
#include <linux/ipv6.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/un.h>
#include <asm/uaccess.h>
#include <linux/inet.h>
#include <linux/idr.h>

#include "debug.h"
#include "v9fs.h"
#include "transport.h"

#define V9FS_PORT 564

struct v9fs_trans_sock {
	struct socket *s;
};

/**
 * v9fs_sock_recv - receive from a socket
 * @v9ses: session information
 * @v: buffer to receive data into
 * @len: size of receive buffer
 *
 */

static int v9fs_sock_recv(struct v9fs_transport *trans, void *v, int len)
{
	struct msghdr msg;
	struct kvec iov;
	int result;
	mm_segment_t oldfs;
	struct v9fs_trans_sock *ts = trans ? trans->priv : NULL;

	if (trans->status == Disconnected)
		return -EREMOTEIO;

	result = -EINVAL;

	oldfs = get_fs();
	set_fs(get_ds());

	iov.iov_base = v;
	iov.iov_len = len;
	msg.msg_name = NULL;
	msg.msg_namelen = 0;
	msg.msg_iovlen = 1;
	msg.msg_control = NULL;
	msg.msg_controllen = 0;
	msg.msg_namelen = 0;
	msg.msg_flags = MSG_NOSIGNAL;

	result = kernel_recvmsg(ts->s, &msg, &iov, 1, len, 0);

	dprintk(DEBUG_TRANS, "socket state %d\n", ts->s->state);
	set_fs(oldfs);

	if (result <= 0) {
		if (result != -ERESTARTSYS)
			trans->status = Disconnected;
	}

	return result;
}

/**
 * v9fs_sock_send - send to a socket
 * @v9ses: session information
 * @v: buffer to send data from
 * @len: size of send buffer
 *
 */

static int v9fs_sock_send(struct v9fs_transport *trans, void *v, int len)
{
	struct kvec iov;
	struct msghdr msg;
	int result = -1;
	mm_segment_t oldfs;
	struct v9fs_trans_sock *ts = trans ? trans->priv : NULL;

	dprintk(DEBUG_TRANS, "Sending packet size %d (%x)\n", len, len);
	dump_data(v, len);

	down(&trans->writelock);

	oldfs = get_fs();
	set_fs(get_ds());
	iov.iov_base = v;
	iov.iov_len = len;
	msg.msg_name = NULL;
	msg.msg_namelen = 0;
	msg.msg_iovlen = 1;
	msg.msg_control = NULL;
	msg.msg_controllen = 0;
	msg.msg_namelen = 0;
	msg.msg_flags = MSG_NOSIGNAL;
	result = kernel_sendmsg(ts->s, &msg, &iov, 1, len);
	set_fs(oldfs);

	if (result < 0) {
		if (result != -ERESTARTSYS)
			trans->status = Disconnected;
	}

	up(&trans->writelock);
	return result;
}

/**
 * v9fs_tcp_init - initialize TCP socket
 * @v9ses: session information
 * @addr: address of server to mount
 * @data: mount options
 *
 */

static int
v9fs_tcp_init(struct v9fs_session_info *v9ses, const char *addr, char *data)
{
	struct socket *csocket = NULL;
	struct sockaddr_in sin_server;
	int rc = 0;
	struct v9fs_trans_sock *ts = NULL;
	struct v9fs_transport *trans = v9ses->transport;

	sema_init(&trans->writelock, 1);
	sema_init(&trans->readlock, 1);

	ts = kmalloc(sizeof(struct v9fs_trans_sock), GFP_KERNEL);

	if (!ts)
		return -ENOMEM;

	trans->priv = ts;
	ts->s = NULL;

	if (!addr)
		return -EINVAL;

	dprintk(DEBUG_TRANS, "Connecting to %s\n", addr);

	sin_server.sin_family = AF_INET;
	sin_server.sin_addr.s_addr = in_aton(addr);
	sin_server.sin_port = htons(v9ses->port);
	sock_create_kern(PF_INET, SOCK_STREAM, IPPROTO_TCP, &csocket);
	rc = csocket->ops->connect(csocket,
				   (struct sockaddr *)&sin_server,
				   sizeof(struct sockaddr_in), 0);
	if (rc < 0) {
		eprintk(KERN_ERR,
			"v9fs_trans_tcp: problem connecting socket to %s\n",
			addr);
		return rc;
	}
	csocket->sk->sk_allocation = GFP_NOIO;
	ts->s = csocket;
	trans->status = Connected;

	return 0;
}

/**
 * v9fs_unix_init - initialize UNIX domain socket
 * @v9ses: session information
 * @dev_name: path to named pipe
 * @data: mount options
 *
 */

static int
v9fs_unix_init(struct v9fs_session_info *v9ses, const char *dev_name,
	       char *data)
{
	int rc;
	struct socket *csocket;
	struct sockaddr_un sun_server;
	struct v9fs_transport *trans;
	struct v9fs_trans_sock *ts;

	rc = 0;
	csocket = NULL;
	trans = v9ses->transport;

	if (strlen(dev_name) > UNIX_PATH_MAX) {
		eprintk(KERN_ERR, "v9fs_trans_unix: address too long: %s\n",
			dev_name);
		return -ENOMEM;
	}

	ts = kmalloc(sizeof(struct v9fs_trans_sock), GFP_KERNEL);
	if (!ts)
		return -ENOMEM;

	trans->priv = ts;
	ts->s = NULL;

	sema_init(&trans->writelock, 1);
	sema_init(&trans->readlock, 1);

	sun_server.sun_family = PF_UNIX;
	strcpy(sun_server.sun_path, dev_name);
	sock_create_kern(PF_UNIX, SOCK_STREAM, 0, &csocket);
	rc = csocket->ops->connect(csocket, (struct sockaddr *)&sun_server,
		sizeof(struct sockaddr_un) - 1, 0);	/* -1 *is* important */
	if (rc < 0) {
		eprintk(KERN_ERR,
			"v9fs_trans_unix: problem connecting socket: %s: %d\n",
			dev_name, rc);
		return rc;
	}
	csocket->sk->sk_allocation = GFP_NOIO;
	ts->s = csocket;
	trans->status = Connected;

	return 0;
}

/**
 * v9fs_sock_close - shutdown socket
 * @trans: private socket structure
 *
 */

static void v9fs_sock_close(struct v9fs_transport *trans)
{
	struct v9fs_trans_sock *ts;

	if (!trans)
		return;

	ts = trans->priv;

	if ((ts) && (ts->s)) {
		dprintk(DEBUG_TRANS, "closing the socket %p\n", ts->s);
		sock_release(ts->s);
		ts->s = NULL;
		trans->status = Disconnected;
		dprintk(DEBUG_TRANS, "socket closed\n");
	}

	kfree(ts);

	trans->priv = NULL;
}

struct v9fs_transport v9fs_trans_tcp = {
	.init = v9fs_tcp_init,
	.write = v9fs_sock_send,
	.read = v9fs_sock_recv,
	.close = v9fs_sock_close,
};

struct v9fs_transport v9fs_trans_unix = {
	.init = v9fs_unix_init,
	.write = v9fs_sock_send,
	.read = v9fs_sock_recv,
	.close = v9fs_sock_close,
};
