/** * 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; }
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); }
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); }
void lime_filter_connect(Filter *source, Filter *sink) { filter_connect(source, 0, sink, 0); }