/**
 * filter_rcv - validate incoming message
 * @sk: socket
 * @buf: message
 *
 * Enqueues message on receive queue if acceptable; optionally handles
 * disconnect indication for a connected socket.
 *
 * Called with socket lock already taken; port lock may also be taken.
 *
 * Returns TIPC error status code (TIPC_OK if message is not to be rejected)
 */
static u32 filter_rcv(struct sock *sk, struct sk_buff *buf)
{
	struct socket *sock = sk->sk_socket;
	struct tipc_msg *msg = buf_msg(buf);
	unsigned int limit = rcvbuf_limit(sk, buf);
	u32 res = TIPC_OK;

	/* Reject message if it is wrong sort of message for socket */
	if (msg_type(msg) > TIPC_DIRECT_MSG)
		return TIPC_ERR_NO_PORT;

	if (sock->state == SS_READY) {
		if (msg_connected(msg))
			return TIPC_ERR_NO_PORT;
	} else {
		res = filter_connect(tipc_sk(sk), &buf);
		if (res != TIPC_OK || buf == NULL)
			return res;
	}

	/* Reject message if there isn't room to queue it */
	if (sk_rmem_alloc_get(sk) + buf->truesize >= limit)
		return TIPC_ERR_OVERLOAD;

	/* Enqueue message */
	TIPC_SKB_CB(buf)->handle = 0;
	__skb_queue_tail(&sk->sk_receive_queue, buf);
	skb_set_owner_r(buf, sk);

	sk->sk_data_ready(sk, 0);
	return TIPC_OK;
}
예제 #2
0
struct ostream *
o_stream_create_ext_filter(struct ostream *output, const char *socket_path,
			   const char *args)
{
	struct mail_filter_ostream *mstream;

	mstream = i_new(struct mail_filter_ostream, 1);
	mstream->fd = -1;
	mstream->ostream.iostream.close = o_stream_mail_filter_close;
	mstream->ostream.sendv = o_stream_mail_filter_sendv;
	mstream->ostream.flush = o_stream_mail_filter_flush;

	(void)filter_connect(mstream, socket_path, args);

	return o_stream_create(&mstream->ostream, output, mstream->fd);
}
예제 #3
0
struct istream *
i_stream_create_ext_filter(struct istream *input, const char *socket_path,
			   const char *args)
{
	struct mail_filter_istream *mstream;

	mstream = i_new(struct mail_filter_istream, 1);
	mstream->istream.iostream.close = i_stream_mail_filter_close;
	mstream->istream.max_buffer_size = input->real_stream->max_buffer_size;
	mstream->istream.read = i_stream_mail_filter_read;
	mstream->istream.stat = i_stream_mail_filter_stat;

	mstream->istream.istream.readable_fd = FALSE;
	mstream->istream.istream.blocking = input->blocking;
	mstream->istream.istream.seekable = FALSE;

	mstream->fd = -1;
	(void)filter_connect(mstream, socket_path, args);

	return i_stream_create(&mstream->istream, input, mstream->fd);
}
예제 #4
0
void lime_filter_connect(Filter *source, Filter *sink)
{
  filter_connect(source, 0, sink, 0);
}