1 /* 2 * twemproxy - A fast and lightweight proxy for memcached protocol. 3 * Copyright (C) 2011 Twitter, 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 _NC_PROTO_H_ 19 #define _NC_PROTO_H_ 20 21 #include <nc_core.h> 22 23 #ifdef NC_LITTLE_ENDIAN 24 25 #define str4cmp(m, c0, c1, c2, c3) \ 26 (*(uint32_t *) m == ((c3 << 24) | (c2 << 16) | (c1 << 8) | c0)) 27 28 #define str5cmp(m, c0, c1, c2, c3, c4) \ 29 (str4cmp(m, c0, c1, c2, c3) && (m[4] == c4)) 30 31 #define str6cmp(m, c0, c1, c2, c3, c4, c5) \ 32 (str4cmp(m, c0, c1, c2, c3) && \ 33 (((uint32_t *) m)[1] & 0xffff) == ((c5 << 8) | c4)) 34 35 #define str7cmp(m, c0, c1, c2, c3, c4, c5, c6) \ 36 (str6cmp(m, c0, c1, c2, c3, c4, c5) && (m[6] == c6)) 37 38 #define str8cmp(m, c0, c1, c2, c3, c4, c5, c6, c7) \ 39 (str4cmp(m, c0, c1, c2, c3) && \ 40 (((uint32_t *) m)[1] == ((c7 << 24) | (c6 << 16) | (c5 << 8) | c4))) 41 42 #define str9cmp(m, c0, c1, c2, c3, c4, c5, c6, c7, c8) \ 43 (str8cmp(m, c0, c1, c2, c3, c4, c5, c6, c7) && m[8] == c8) 44 45 #define str10cmp(m, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9) \ 46 (str8cmp(m, c0, c1, c2, c3, c4, c5, c6, c7) && \ 47 (((uint32_t *) m)[2] & 0xffff) == ((c9 << 8) | c8)) 48 49 #define str11cmp(m, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10) \ 50 (str10cmp(m, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9) && (m[10] == c10)) 51 52 #define str12cmp(m, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11) \ 53 (str8cmp(m, c0, c1, c2, c3, c4, c5, c6, c7) && \ 54 (((uint32_t *) m)[2] == ((c11 << 24) | (c10 << 16) | (c9 << 8) | c8))) 55 56 #else 57 58 #define str4cmp(m, c0, c1, c2, c3) \ 59 (m[0] == c0 && m[1] == c1 && m[2] == c2 && m[3] == c3) 60 61 #define str5cmp(m, c0, c1, c2, c3, c4) \ 62 (str4cmp(m, c0, c1, c2, c3) && (m[4] == c4)) 63 64 #define str6cmp(m, c0, c1, c2, c3, c4, c5) \ 65 (str5cmp(m, c0, c1, c2, c3, c4) && m[5] == c5) 66 67 #define str7cmp(m, c0, c1, c2, c3, c4, c5, c6) \ 68 (str6cmp(m, c0, c1, c2, c3, c4, c5) && m[6] == c6) 69 70 #define str8cmp(m, c0, c1, c2, c3, c4, c5, c6, c7) \ 71 (str7cmp(m, c0, c1, c2, c3, c4, c5, c6) && m[7] == c7) 72 73 #define str9cmp(m, c0, c1, c2, c3, c4, c5, c6, c7, c8) \ 74 (str8cmp(m, c0, c1, c2, c3, c4, c5, c6, c7) && m[8] == c8) 75 76 #define str10cmp(m, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9) \ 77 (str9cmp(m, c0, c1, c2, c3, c4, c5, c6, c7, c8) && m[9] == c9) 78 79 #define str11cmp(m, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10) \ 80 (str10cmp(m, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9) && m[10] == c10) 81 82 #define str12cmp(m, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11) \ 83 (str11cmp(m, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10) && m[11] == c11) 84 85 #endif 86 87 #define str3icmp(m, c0, c1, c2) \ 88 ((m[0] == c0 || m[0] == (c0 ^ 0x20)) && \ 89 (m[1] == c1 || m[1] == (c1 ^ 0x20)) && \ 90 (m[2] == c2 || m[2] == (c2 ^ 0x20))) 91 92 #define str4icmp(m, c0, c1, c2, c3) \ 93 (str3icmp(m, c0, c1, c2) && (m[3] == c3 || m[3] == (c3 ^ 0x20))) 94 95 #define str5icmp(m, c0, c1, c2, c3, c4) \ 96 (str4icmp(m, c0, c1, c2, c3) && (m[4] == c4 || m[4] == (c4 ^ 0x20))) 97 98 #define str6icmp(m, c0, c1, c2, c3, c4, c5) \ 99 (str5icmp(m, c0, c1, c2, c3, c4) && (m[5] == c5 || m[5] == (c5 ^ 0x20))) 100 101 #define str7icmp(m, c0, c1, c2, c3, c4, c5, c6) \ 102 (str6icmp(m, c0, c1, c2, c3, c4, c5) && \ 103 (m[6] == c6 || m[6] == (c6 ^ 0x20))) 104 105 #define str8icmp(m, c0, c1, c2, c3, c4, c5, c6, c7) \ 106 (str7icmp(m, c0, c1, c2, c3, c4, c5, c6) && \ 107 (m[7] == c7 || m[7] == (c7 ^ 0x20))) 108 109 #define str9icmp(m, c0, c1, c2, c3, c4, c5, c6, c7, c8) \ 110 (str8icmp(m, c0, c1, c2, c3, c4, c5, c6, c7) && \ 111 (m[8] == c8 || m[8] == (c8 ^ 0x20))) 112 113 #define str10icmp(m, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9) \ 114 (str9icmp(m, c0, c1, c2, c3, c4, c5, c6, c7, c8) && \ 115 (m[9] == c9 || m[9] == (c9 ^ 0x20))) 116 117 #define str11icmp(m, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10) \ 118 (str10icmp(m, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9) && \ 119 (m[10] == c10 || m[10] == (c10 ^ 0x20))) 120 121 #define str12icmp(m, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11) \ 122 (str11icmp(m, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10) && \ 123 (m[11] == c11 || m[11] == (c11 ^ 0x20))) 124 125 #define str13icmp(m, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12) \ 126 (str12icmp(m, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11) && \ 127 (m[12] == c12 || m[12] == (c12 ^ 0x20))) 128 129 #define str14icmp(m, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13) \ 130 (str13icmp(m, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12) && \ 131 (m[13] == c13 || m[13] == (c13 ^ 0x20))) 132 133 #define str15icmp(m, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14) \ 134 (str14icmp(m, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13) && \ 135 (m[14] == c14 || m[14] == (c14 ^ 0x20))) 136 137 #define str16icmp(m, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15) \ 138 (str15icmp(m, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14) && \ 139 (m[15] == c15 || m[15] == (c15 ^ 0x20))) 140 141 #define str17icmp(m, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16) \ 142 (str16icmp(m, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15) && \ 143 (m[16] == c16 || m[16] == (c16 ^ 0x20))) 144 145 void memcache_parse_req(struct msg *r); 146 void memcache_parse_rsp(struct msg *r); 147 bool memcache_failure(const struct msg *r); 148 void memcache_pre_coalesce(struct msg *r); 149 void memcache_post_coalesce(struct msg *r); 150 rstatus_t memcache_add_auth(struct context *ctx, struct conn *c_conn, struct conn *s_conn); 151 rstatus_t memcache_fragment(struct msg *r, uint32_t nserver, struct msg_tqh *frag_msgq); 152 rstatus_t memcache_reply(struct msg *r); 153 void memcache_post_connect(struct context *ctx, struct conn *conn, struct server *server); 154 void memcache_swallow_msg(struct conn *conn, struct msg *pmsg, struct msg *msg); 155 156 void redis_parse_req(struct msg *r); 157 void redis_parse_rsp(struct msg *r); 158 bool redis_failure(const struct msg *r); 159 void redis_pre_coalesce(struct msg *r); 160 void redis_post_coalesce(struct msg *r); 161 rstatus_t redis_add_auth(struct context *ctx, struct conn *c_conn, struct conn *s_conn); 162 rstatus_t redis_fragment(struct msg *r, uint32_t nserver, struct msg_tqh *frag_msgq); 163 rstatus_t redis_reply(struct msg *r); 164 void redis_post_connect(struct context *ctx, struct conn *conn, struct server *server); 165 void redis_swallow_msg(struct conn *conn, struct msg *pmsg, struct msg *msg); 166 167 #endif 168