1 /* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /*
3  *     Copyright 2014 Couchbase, Inc.
4  *
5  *   Licensed under the Apache License, Version 2.0 (the "License");
6  *   you may not use this file except in compliance with the License.
7  *   You may obtain a copy of the License at
8  *
9  *       http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *   Unless required by applicable law or agreed to in writing, software
12  *   distributed under the License is distributed on an "AS IS" BASIS,
13  *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *   See the License for the specific language governing permissions and
15  *   limitations under the License.
16  */
17 
18 #ifndef MC_FORWARD_H
19 #define MC_FORWARD_H
20 #ifdef __cplusplus
21 extern "C" {
22 #endif
23 
24 #include "iovcursor.h"
25 
26 
27 /**
28  * Copy over the entire packet to the internal buffers. Input buffer is
29  * temporary.
30  */
31 #define MC_FWD_OPT_COPY 0x01
32 
33 /**
34  * The server to send to is already set as `pl`. Don't perform vbucket mapping.
35  */
36 #define MC_FWD_OPT_NOMAP 0x02
37 
38 void
39 mc_iovinfo_init(mc_IOVINFO *info, const nb_IOV *iov, unsigned niov);
40 
41 /**
42  * Forward a packet to an upstream server.
43  * @param[in] cq the command queue
44  * @param[in] ctx a queue context used for scheduling/flushing the packets
45  * @param[in] info an 'IOVINFO' structure. See the structure documentation for
46  *        more details.
47  * @param[out] pkt a pointer to a packet, set to the resultant packet structure
48  * @param[out] pl the pipeline this packet is mapped to
49  * @param options Options modifying the behavior of this operation
50  * @return LCB_SUCCESS or an error code.
51  *
52  * Currently only some commands will successfully make sense to forward. This
53  * function only handles the lower level aspect of actually allocating or
54  * reserving the buffers required to forward the packet, but not actually
55  * handling the received data for the callbacks themselves.
56  *
57  * Note that this function does not currently "Collapse" consectutive IOV
58  * structures. Additionally the following should be noted:
59  *
60  * <ol>
61  * <li>
62  *     If the first IOV does not contain a contiguous buffer of the
63  *     { header, extras, key }, then it will be copied into a library-based
64  *     buffer.
65  * </li>
66  *
67  * <li>
68  *     If the total number of IOVs is greater than two, then niov-1 IOV
69  *     structures will be allocated via 'malloc'. This may not always happen
70  *     if the header _itself_ is fragmented
71  * </li>
72  *
73  * <li>The first 24 bytes of the header WILL BE MODIFIED by the library.
74  *     This will be used to modify the 'opaque' and 'vbucket' fields.
75  *     Take this into note if you need to keep track of their original values.
76  * </li>
77  *
78  * <li>Check the 'niov' counter to see if it is 0. If it's 0 then you should
79  *     make sure to reset the counter.
80  * </li>
81  * </ol>
82  */
83 lcb_error_t
84 mc_forward_packet(mc_CMDQUEUE *cq,
85     mc_IOVINFO *info, mc_PACKET **pkt, mc_PIPELINE **pl, int options);
86 
87 #ifdef __cplusplus
88 }
89 #endif
90 #endif
91