コード例 #1
0
/*
 * Having read count bytes from a socket, check whether it
 * needs to be re-enqueued.
 */
static inline void
svc_sock_received(struct svc_sock *svsk, int count)
{
	start_bh_atomic();
	if ((svsk->sk_data -= count) < 0) {
		printk(KERN_NOTICE "svc: sk_data negative!\n");
		svsk->sk_data = 0;
	}
	svsk->sk_rqstp = NULL; /* XXX */
	svsk->sk_busy = 0;
	if (svsk->sk_conn || svsk->sk_data || svsk->sk_close) {
		dprintk("svc: socket %p re-enqueued after receive\n",
						svsk->sk_sk);
		svc_sock_enqueue(svsk);
	}
	end_bh_atomic();
}
コード例 #2
0
ファイル: svcsock.c プロジェクト: iwangv/edimax-br-6528n
static void
svc_tcp_data_ready(struct sock *sk, int count)
{
	struct svc_sock *	svsk;

	dprintk("svc: socket %p TCP data ready (svsk %p)\n",
			sk, sk->user_data);
	if (!(svsk = (struct svc_sock *)(sk->user_data)))
		goto out;
	spin_lock_bh(&svsk->sk_lock);
	svsk->sk_data++;
	svc_sock_enqueue(svsk);
	spin_unlock_bh(&svsk->sk_lock);
 out:
	if (sk->sleep && waitqueue_active(sk->sleep))
		wake_up_interruptible(sk->sleep);
}
コード例 #3
0
ファイル: svcsock.c プロジェクト: iwangv/edimax-br-6528n
/*
 * INET callback when data has been received on the socket.
 */
static void
svc_udp_data_ready(struct sock *sk, int count)
{
	struct svc_sock	*svsk = (struct svc_sock *)(sk->user_data);

	if (!svsk)
		goto out;
	dprintk("svc: socket %p(inet %p), count=%d, busy=%d\n",
		svsk, sk, count, svsk->sk_busy);
	spin_lock_bh(&svsk->sk_lock);
	svsk->sk_data = 1;
	svc_sock_enqueue(svsk);
	spin_unlock_bh(&svsk->sk_lock);
 out:
	if (sk->sleep && waitqueue_active(sk->sleep))
		wake_up_interruptible(sk->sleep);
}
コード例 #4
0
static void
svc_tcp_data_ready(struct sock *sk, int count)
{
	struct svc_sock *	svsk;

	/* Disconnect signalled through data_ready?!? */
	if (sk->state != TCP_ESTABLISHED) {
		svc_tcp_state_change2(sk);
		return;
	}

	dprintk("svc: socket %p TCP data ready (svsk %p)\n",
			sk, sk->user_data);
	if (!(svsk = (struct svc_sock *)(sk->user_data)))
		return;
	svsk->sk_data++;
	svc_sock_enqueue(svsk);
}
コード例 #5
0
/*
 * A state change on a listening socket means there's a connection
 * pending.
 */
static void
svc_tcp_state_change1(struct sock *sk)
{
	struct svc_sock	*svsk;

	dprintk("svc: socket %p TCP (listen) state change %d\n",
			sk, sk->state);

	if  (sk->state != TCP_ESTABLISHED) {
		/* Aborted connection, SYN_RECV or whatever... */
		return;
	}
	if (!(svsk = (struct svc_sock *) sk->user_data)) {
		printk("svc: socket %p: no user data\n", sk);
		return;
	}
	svsk->sk_conn++;
	svc_sock_enqueue(svsk);
}
コード例 #6
0
ファイル: svcsock.c プロジェクト: dmgerman/original
/*
 * A state change on a connected socket means it's dying or dead.
 */
static void
svc_tcp_state_change2(struct sock *sk)
{
	struct svc_sock	*svsk;

	dprintk("svc: socket %p TCP (connected) state change %d (svsk %p)\n",
			sk, sk->state, sk->user_data);

	if (!(svsk = (struct svc_sock *) sk->user_data)) {
		printk("svc: socket %p: no user data\n", sk);
		goto out;
	}
	spin_lock_bh(&svsk->sk_lock);
	svsk->sk_close = 1;
	svc_sock_enqueue(svsk);
	spin_unlock_bh(&svsk->sk_lock);
 out:
	if (sk->sleep && waitqueue_active(sk->sleep))
		wake_up_interruptible_all(sk->sleep);
}
コード例 #7
0
ファイル: svcsock.c プロジェクト: dmgerman/original
/*
 * A state change on a listening socket means there's a connection
 * pending.
 */
static void
svc_tcp_state_change1(struct sock *sk)
{
	struct svc_sock	*svsk;

	dprintk("svc: socket %p TCP (listen) state change %d\n",
			sk, sk->state);

	if  (sk->state != TCP_ESTABLISHED) {
		/* Aborted connection, SYN_RECV or whatever... */
		goto out;
	}
	if (!(svsk = (struct svc_sock *) sk->user_data)) {
		printk("svc: socket %p: no user data\n", sk);
		goto out;
	}
	spin_lock_bh(&svsk->sk_lock);
	svsk->sk_conn++;
	svc_sock_enqueue(svsk);
	spin_unlock_bh(&svsk->sk_lock);
 out:
	if (sk->sleep && waitqueue_active(sk->sleep))
		wake_up_interruptible_all(sk->sleep);
}
コード例 #8
0
ファイル: svcsock.c プロジェクト: dmgerman/original
/*
 * Accept a TCP connection
 */
static void
svc_tcp_accept(struct svc_sock *svsk)
{
	struct sockaddr_in sin;
	struct svc_serv	*serv = svsk->sk_server;
	struct socket	*sock = svsk->sk_sock;
	struct socket	*newsock;
	struct proto_ops *ops;
	struct svc_sock	*newsvsk;
	int		err, slen;

	dprintk("svc: tcp_accept %p sock %p\n", svsk, sock);
	if (!sock)
		return;

	if (!(newsock = sock_alloc())) {
		printk(KERN_WARNING "%s: no more sockets!\n", serv->sv_name);
		return;
	}
	dprintk("svc: tcp_accept %p allocated\n", newsock);

	newsock->type = sock->type;
	newsock->ops = ops = sock->ops;

	if ((err = ops->accept(sock, newsock, O_NONBLOCK)) < 0) {
		if (net_ratelimit())
			printk(KERN_WARNING "%s: accept failed (err %d)!\n",
				   serv->sv_name, -err);
		goto failed;		/* aborted connection or whatever */
	}

	slen = sizeof(sin);
	err = ops->getname(newsock, (struct sockaddr *) &sin, &slen, 1);
	if (err < 0) {
		if (net_ratelimit())
			printk(KERN_WARNING "%s: peername failed (err %d)!\n",
				   serv->sv_name, -err);
		goto failed;		/* aborted connection or whatever */
	}

	/* Ideally, we would want to reject connections from unauthorized
	 * hosts here, but when we get encription, the IP of the host won't
	 * tell us anything. For now just warn about unpriv connections.
	 */
	if (ntohs(sin.sin_port) >= 1024) {
		if (net_ratelimit())
			printk(KERN_WARNING
				   "%s: connect from unprivileged port: %u.%u.%u.%u:%d\n",
				   serv->sv_name, 
				   NIPQUAD(sin.sin_addr.s_addr), ntohs(sin.sin_port));
	}

	dprintk("%s: connect from %u.%u.%u.%u:%04x\n", serv->sv_name,
			NIPQUAD(sin.sin_addr.s_addr), ntohs(sin.sin_port));

	if (!(newsvsk = svc_setup_socket(serv, newsock, &err, 0)))
		goto failed;

	/* Precharge. Data may have arrived on the socket before we
	 * installed the data_ready callback. 
	 */
	spin_lock_bh(&newsvsk->sk_lock);
	newsvsk->sk_data = 1;
	newsvsk->sk_temp = 1;
	svc_sock_enqueue(newsvsk);
	spin_unlock_bh(&newsvsk->sk_lock);

	if (serv->sv_stats)
		serv->sv_stats->nettcpconn++;

	return;

failed:
	sock_release(newsock);
	return;
}
コード例 #9
0
/*
 * Accept a TCP connection
 */
static void
svc_tcp_accept(struct svc_sock *svsk)
{
	struct sockaddr_in sin;
	struct svc_serv	*serv = svsk->sk_server;
	struct socket	*sock = svsk->sk_sock;
	struct socket	*newsock;
	struct proto_ops *ops;
	struct svc_sock	*newsvsk;
	int		err, slen;

	dprintk("svc: tcp_accept %p sock %p\n", svsk, sock);
	if (!sock)
		return;

	if (!(newsock = sock_alloc())) {
		printk(KERN_WARNING "%s: no more sockets!\n", serv->sv_name);
		return;
	}
	dprintk("svc: tcp_accept %p allocated\n", newsock);

	newsock->type = sock->type;
	if ((err = sock->ops->dup(newsock, sock)) < 0) {
		printk(KERN_WARNING "%s: socket dup failed (err %d)!\n",
					serv->sv_name, -err);
		goto failed;
	}

	ops = newsock->ops;
	if ((err = ops->accept(sock, newsock, O_NONBLOCK)) < 0) {
		printk(KERN_WARNING "%s: accept failed (err %d)!\n",
					serv->sv_name, -err);
		goto failed;		/* aborted connection or whatever */
	}

	slen = sizeof(sin);
	err = ops->getname(newsock, (struct sockaddr *) &sin, &slen, 1);
	if (err < 0) {
		printk(KERN_WARNING "%s: peername failed (err %d)!\n",
					serv->sv_name, -err);
		goto failed;		/* aborted connection or whatever */
	}

	/* Ideally, we would want to reject connections from unauthorized
	 * hosts here, but we have no generic client tables. For now,
	 * we just punt connects from unprivileged ports. */
	if (ntohs(sin.sin_port) >= 1024) {
		printk(KERN_WARNING
			"%s: connect from unprivileged port: %08lx:%d",
			serv->sv_name, 
			ntohl(sin.sin_addr.s_addr), ntohs(sin.sin_port));
		goto failed;
	}

	dprintk("%s: connect from %08lx:%04x\n", serv->sv_name,
			ntohl(sin.sin_addr.s_addr), ntohs(sin.sin_port));

	if (!(newsvsk = svc_setup_socket(serv, newsock, &err, 0)))
		goto failed;

	/* Precharge. Data may have arrived on the socket before we
	 * installed the data_ready callback. 
	 */
	newsvsk->sk_data = 1;
	newsvsk->sk_temp = 1;
	svc_sock_enqueue(newsvsk);

	if (serv->sv_stats)
		serv->sv_stats->nettcpconn++;

	return;

failed:
	sock_release(newsock);
	return;
}