All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
as_proto.h
Go to the documentation of this file.
1 /*
2  * Copyright 2008-2019 Aerospike, Inc.
3  *
4  * Portions may be licensed to Aerospike, Inc. under one or more contributor
5  * license agreements.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
8  * use this file except in compliance with the License. You may obtain a copy of
9  * the License at 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, WITHOUT
13  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14  * License for the specific language governing permissions and limitations under
15  * the License.
16  */
17 #pragma once
18 
19 #include <aerospike/as_std.h>
20 #include <aerospike/as_error.h>
21 #include <citrusleaf/cf_byte_order.h>
22 #include <stddef.h>
23 
24 #ifdef __cplusplus
25 extern "C" {
26 #endif
27 
28 /******************************************************************************
29  * MACROS
30  *****************************************************************************/
31 
32 // Proto header version
33 #define AS_PROTO_VERSION 2
34 
35 // Proto message types
36 #define AS_INFO_MESSAGE_TYPE 1
37 #define AS_ADMIN_MESSAGE_TYPE 2
38 #define AS_MESSAGE_TYPE 3
39 #define AS_COMPRESSED_MESSAGE_TYPE 4
40 #define PROTO_SIZE_MAX (128 * 1024 * 1024)
41 
42 /******************************************************************************
43  * TYPES
44  *****************************************************************************/
45 
46 #if defined(__APPLE__) || defined(_MSC_VER)
47 
48 #pragma pack(push, 1) // packing is now 1
49 typedef struct as_proto_s {
50  uint64_t version :8;
51  uint64_t type :8;
52  uint64_t sz :48;
53 } as_proto;
54 #pragma pack(pop) // packing is back to what it was
55 
56 #pragma pack(push, 1) // packing is now 1
57 typedef struct as_compressed_proto_s {
58  as_proto proto;
59  uint64_t uncompressed_sz;
60 } as_compressed_proto;
61 #pragma pack(pop) // packing is back to what it was
62 
63 #pragma pack(push, 1) // packing is now 1
64 typedef struct as_msg_s {
65 /*00*/ uint8_t header_sz; // number of uint8_ts in this header
66 /*01*/ uint8_t info1; // bitfield about this request
67 /*02*/ uint8_t info2;
68 /*03*/ uint8_t info3;
69 /*04*/ uint8_t unused;
70 /*05*/ uint8_t result_code;
71 /*06*/ uint32_t generation;
72 /*10*/ uint32_t record_ttl;
73 /*14*/ uint32_t transaction_ttl; // milliseconds
74 /*18*/ uint16_t n_fields; // size in uint8_ts
75 /*20*/ uint16_t n_ops; // number of operations
76 /*22*/ uint8_t data[0]; // data contains first the fields, then the ops
77 } as_msg;
78 #pragma pack(pop) // packing is back to what it was
79 
80 #pragma pack(push, 1) // packing is now 1
81 typedef struct as_proto_msg_s {
82  as_proto proto;
83  as_msg m;
84 } as_proto_msg;
85 #pragma pack(pop) // packing is back to what it was
86 
87 #else
88 
89 typedef struct as_proto_s {
90  uint8_t version;
91  uint8_t type;
92  uint64_t sz :48;
93  uint8_t data[0];
94 } __attribute__ ((__packed__)) as_proto;
95 
96 typedef struct as_compressed_proto_s {
97  as_proto proto;
98  uint64_t uncompressed_sz;
99  uint8_t data[0]; // compressed bytes
100 } __attribute__((__packed__)) as_compressed_proto;
101 
102 typedef struct as_msg_s {
103 /*00*/ uint8_t header_sz; // number of uint8_ts in this header
104 /*01*/ uint8_t info1; // bitfield about this request
105 /*02*/ uint8_t info2;
106 /*03*/ uint8_t info3;
107 /*04*/ uint8_t unused;
108 /*05*/ uint8_t result_code;
109 /*06*/ uint32_t generation;
110 /*10*/ uint32_t record_ttl;
111 /*14*/ uint32_t transaction_ttl;
112 /*18*/ uint16_t n_fields; // size in uint8_ts
113 /*20*/ uint16_t n_ops; // number of operations
114 /*22*/ uint8_t data[0]; // data contains first the fields, then the ops
115 } __attribute__((__packed__)) as_msg;
116 
117 typedef struct as_proto_msg_s {
118  as_proto proto;
119  as_msg m;
120 } __attribute__((__packed__)) as_proto_msg;
121 
122 #endif
123 
124 /******************************************************************************
125  * FUNCTIONS
126  ******************************************************************************/
127 
128 void as_proto_swap_to_be(as_proto *m);
129 void as_proto_swap_from_be(as_proto *m);
130 void as_msg_swap_header_from_be(as_msg *m);
132 as_status as_proto_type_error(as_error* err, as_proto* proto, uint8_t expected);
133 as_status as_proto_size_error(as_error* err, size_t size);
134 as_status as_compressed_size_error(as_error* err, size_t size);
135 as_status as_proto_parse(as_error* err, as_proto* proto);
136 as_status as_proto_decompress(as_error* err, uint8_t* trg, size_t trg_sz, uint8_t* src, size_t src_sz);
137 
138 static inline as_status
139 as_proto_parse_type(as_error* err, as_proto* proto, uint8_t expected_type)
140 {
141  if (proto->type != expected_type) {
142  return as_proto_type_error(err, proto, expected_type);
143  }
144  return as_proto_parse(err, proto);
145 }
146 
147 static inline as_status
148 as_msg_parse(as_error* err, as_msg* msg, size_t size)
149 {
150  if (size < sizeof(as_msg)) {
151  return as_proto_size_error(err, size);
152  }
154  return AEROSPIKE_OK;
155 }
156 
157 static inline as_status
158 as_compressed_size_parse(as_error* err, const uint8_t* buf, size_t* size)
159 {
160  *size = (size_t)cf_swap_from_be64(*(uint64_t*)buf);
161 
162  if (*size > PROTO_SIZE_MAX) {
163  return as_compressed_size_error(err, *size);
164  }
165  return AEROSPIKE_OK;
166 }
167 
168 #ifdef __cplusplus
169 } // end extern "C"
170 #endif
uint8_t result_code
Definition: as_proto.h:108
as_proto proto
Definition: as_proto.h:118
as_msg m
Definition: as_proto.h:36
uint32_t record_ttl
Definition: as_proto.h:110
as_status as_proto_version_error(as_error *err, as_proto *proto)
as_status
Definition: as_status.h:30
void as_proto_swap_from_be(as_proto *m)
uint16_t n_ops
Definition: as_proto.h:113
uint64_t uncompressed_sz
Definition: as_proto.h:98
uint32_t generation
Definition: as_proto.h:109
static as_status as_compressed_size_parse(as_error *err, const uint8_t *buf, size_t *size)
Definition: as_proto.h:158
as_proto proto
Definition: as_proto.h:35
uint8_t info3
Definition: as_proto.h:106
#define PROTO_SIZE_MAX
Definition: as_proto.h:40
uint32_t transaction_ttl
Definition: as_proto.h:111
uint8_t version
Definition: as_proto.h:90
uint8_t data[0]
Definition: as_proto.h:93
uint8_t data[0]
Definition: as_proto.h:114
as_status as_proto_decompress(as_error *err, uint8_t *trg, size_t trg_sz, uint8_t *src, size_t src_sz)
as_status as_proto_size_error(as_error *err, size_t size)
uint8_t unused
Definition: as_proto.h:107
uint8_t info1
Definition: as_proto.h:104
static as_status as_proto_parse_type(as_error *err, as_proto *proto, uint8_t expected_type)
Definition: as_proto.h:139
uint8_t header_sz
Definition: as_proto.h:103
uint8_t data[0]
Definition: as_proto.h:38
static as_status as_msg_parse(as_error *err, as_msg *msg, size_t size)
Definition: as_proto.h:148
uint8_t type
Definition: as_proto.h:91
as_status as_proto_type_error(as_error *err, as_proto *proto, uint8_t expected)
as_status as_proto_parse(as_error *err, as_proto *proto)
uint8_t info2
Definition: as_proto.h:105
void as_msg_swap_header_from_be(as_msg *m)
as_status as_compressed_size_error(as_error *err, size_t size)
uint64_t sz
Definition: as_proto.h:92
uint16_t n_fields
Definition: as_proto.h:112
void as_proto_swap_to_be(as_proto *m)