1 /* 2 Copyright (C) 2008-2017, Millistream Market Data <support@millistream.com> 3 4 This program is free software: you can redistribute it and/or modify 5 it under the terms of the GNU Lesser General Public License as published by 6 the Free Software Foundation, either version 3 of the License, or 7 (at your option) any later version. 8 9 This program is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU General Public License for more details. 13 14 You should have received a copy of the GNU Lesser General Public License 15 along with this program. If not, see <http://www.gnu.org/licenses/>. 16 17 */ 18 19 #ifndef MDFCOMMON_H 20 # define MDFCOMMON_H 1 21 22 # ifdef HAVE_CONFIG_H 23 # include "../config.h" 24 # endif 25 # ifdef HAVE_STDLIB_H 26 # include <stdlib.h> 27 # endif 28 # ifdef HAVE_UNISTD_H 29 # include <unistd.h> 30 # endif 31 # include <stdio.h> 32 # ifdef HAVE_STDINT_H 33 # include <stdint.h> 34 # elif _MSC_VER >= 1600 35 # include <stdint.h> 36 # define _STDINT_H 1 /* so we ignore the check in mdf.h */ 37 # elif _MSC_VER 38 # define uint8_t unsigned __int8 39 # define uint16_t unsigned __int16 40 # define uint32_t unsigned __int32 41 # define uint64_t unsigned __int64 42 # define int64_t __int64 43 # define _STDINT_H 1 /* so we ignore the check in mdf.h */ 44 # else 45 # define uint8_t unsigned char 46 # define uint16_t unsigned short 47 # define uint32_t unsigned int 48 # define uint64_t unsigned long long 49 # define int64_t long long 50 # define _STDINT_H 1 /* so we ignore the check in mdf.h */ 51 # endif 52 53 # ifdef HAVE_INTTYPES_H 54 # include <inttypes.h> 55 # elif _MSC_VER 56 # define PRIu64 "I64u" 57 # else 58 # define PRIu64 "llu" 59 # endif 60 61 # ifndef __UINT64_C 62 # ifdef UINT64_C 63 # define __UINT64_C(c) UINT64_C(c) 64 # elif _MSC_VER 65 # define __UINT64_C(c) c##ui64 66 # else 67 # define __UINT64_C(c) c##ULL 68 # endif 69 # endif 70 71 # ifndef HAVE_STRTOULL 72 # if _MSC_VER >= 1300 73 # define strtoull(a,b,c) _strtoui64(a,b,c) 74 # elif HAVE_STRTOQ 75 # define strtoull(a,b,c) strtoq(a,b,c) 76 # else 77 # define strtoull(a,b,c) strtoul(a,b,c) 78 # endif 79 # endif 80 81 # ifdef HAVE_STRING_H 82 # include <string.h> 83 # endif 84 # ifdef HAVE_SYS_IOCTL_H 85 # include <sys/ioctl.h> 86 # endif 87 # ifdef HAVE_SYS_FILIO_H 88 # include <sys/filio.h> 89 # endif 90 # ifdef HAVE_SYS_TYPES_H 91 # include <sys/types.h> 92 # endif 93 # ifdef HAVE_SYS_SOCKET_H 94 # include <sys/socket.h> 95 # endif 96 # ifdef HAVE_SYS_UN_H 97 # include <sys/un.h> 98 # endif 99 # ifdef HAVE_NETINET_IN_H 100 # include <netinet/in.h> 101 # endif 102 # ifdef HAVE_NETINET_TCP_H 103 # include <netinet/tcp.h> 104 # endif 105 # ifdef HAVE_NETDB_H 106 # include <netdb.h> 107 # endif 108 # ifdef HAVE_FCNTL_H 109 # include <fcntl.h> 110 # endif 111 # ifdef HAVE_ERRNO_H 112 # include <errno.h> 113 # endif 114 # ifdef HAVE_SIGNAL_H 115 # include <signal.h> 116 # endif 117 # ifdef HAVE_TIME_H 118 # include <time.h> 119 # endif 120 # if defined _WIN32 || defined _WIN64 121 # include <stddef.h> 122 # include <time.h> 123 # include <limits.h> 124 # include <winsock2.h> 125 # include <ws2tcpip.h> 126 # define MSG_NOSIGNAL 0 127 # else 128 # define INVALID_SOCKET -1 129 # endif 130 # include <ctype.h> 131 # include <stdarg.h> 132 # include <zlib.h> 133 # include <openssl/opensslv.h> 134 # include <openssl/objects.h> 135 # include <openssl/rand.h> 136 # include <openssl/bio.h> 137 # include <openssl/dh.h> 138 # include <openssl/rsa.h> 139 # include <openssl/hmac.h> 140 # include <openssl/pem.h> 141 # include <openssl/aes.h> 142 # if defined HAVE_OPENSSL_MD5_H && !defined OPENSSL_NO_MD5 143 # include <openssl/md5.h> 144 # endif 145 # if defined HAVE_OPENSSL_SHA_H && !defined OPENSSL_NO_SHA 146 # include <openssl/sha.h> 147 # endif 148 # if defined HAVE_OPENSSL_RIPEMD_H && !defined OPENSSL_NO_RIPEMD 149 # include <openssl/ripemd.h> 150 # endif 151 # if defined HAVE_OPENSSL_WHRLPOOL_H && !defined OPENSSL_NO_WHIRLPOOL 152 # include <openssl/whrlpool.h> 153 # endif 154 # include "mdf_byteswap.h" 155 # include "mdf.h" 156 # include "mdf_fields.h" 157 # include "version.h" 158 # if _MSC_VER >= 1300 159 # define strdup(s) _strdup(s) 160 # endif 161 # ifndef SOL_TCP 162 # define SOL_TCP IPPROTO_TCP 163 # endif 164 # ifndef SOCK_CLOEXEC 165 # define SOCK_CLOEXEC 0 166 # endif 167 168 # if (defined LIBRESSL_VERSION_NUMBER && OPENSSL_VERSION_NUMBER == 0x20000000L) 169 # undef OPENSSL_VERSION_NUMBER 170 # define OPENSSL_VERSION_NUMBER 0x1000107fL 171 # endif 172 173 #define NELEMS(x) ((int)(sizeof x/sizeof x[0])) 174 #define MAX_RECORDLENGTH (64 * 1024 * 1024) 175 176 #define CSTATE_ENCRYPT 1 177 #define CSTATE_DECRYPT 2 178 #define CSTATE_INVALID 4 /* prevents mdf_consume() and mdf_message_send() to do anything until the handshake is completed */ 179 180 struct msg_field { 181 int pos; 182 uint32_t tag; 183 }; 184 185 struct msg_template { 186 int mclass; 187 int tags_num; 188 uint32_t *tags; 189 struct msg_field *fields; 190 }; 191 192 struct callbacks { 193 void *udata_data; 194 void *udata_status; 195 mdf_data_callback func_data; 196 mdf_status_callback func_status; 197 }; 198 199 struct mdf_s { 200 uint64_t insref; 201 uint64_t bytes_read; 202 uint64_t bytes_written; 203 uint64_t template_version; 204 uint8_t *data; 205 uint8_t *value; 206 uint8_t *master_secret; 207 uint8_t *client_iv; 208 uint8_t *server_iv; 209 AES_KEY *client_enc; 210 AES_KEY *server_enc; 211 HMAC_CTX *client_hmac; 212 HMAC_CTX *server_hmac; 213 struct msg_template *templates; 214 struct field **sendfields; 215 struct field **sendtags; 216 uint8_t *sendbuf; 217 char *connected_host; 218 char *connected_ip; 219 struct callbacks callbacks; 220 time_t time_lastupdate; 221 size_t pos; /* points at the current pmap */ 222 size_t fpos; /* points at the current field */ 223 size_t vlen; /* length of value in bytes */ 224 size_t data_pos; /* current decoding position in the data buffer */ 225 size_t data_used; /* current read position in the data buffer */ 226 size_t data_size; /* total size of the data buffer */ 227 size_t message_len; /* the total message length including any message digest */ 228 size_t message_end; /* points to the last byte of the message (not including the digest) */ 229 int templates_num; 230 int sendfields_num; 231 unsigned int sendtags_num; 232 int sendbuf_size; 233 int in_pmap_pos; /* bit position in the current pmap, 128,96,64,32,16,8,4,1 */ 234 int field_pmap_pos; /* current field position */ 235 int fstatus; 236 int connect_timeout; 237 int heartbeats_sent; 238 int heartbeat_interval; 239 int max_missed_heartbeats; 240 int cstate; 241 int encryption_method; 242 int digest_method; 243 int digest_length; 244 int tcp_nodelay; 245 int no_encryption; 246 int timediff; 247 MDF_ERROR error; 248 # if defined _WIN32 || defined _WIN64 249 SOCKET fd; 250 # else 251 int fd; 252 # endif 253 uint16_t msgref; 254 uint8_t oldval; /* carries the byte that we zero out when reading messages */ 255 }; 256 257 void mdf_int_send_rekey (mdf_t handle); 258 void mdf_int_encrypt_aes_ctr (uint8_t * restrict out, const size_t len, AES_KEY *key, uint8_t * restrict iv); 259 int mdf_int_decrypt_data (mdf_t handle, uint8_t *data, const uint32_t len, const int pos); 260 int mdf_int_send_heartbeat (mdf_t handle); 261 void mdf_int_rebalance_templates (struct msg_template * const templates, const int templates_num); 262 263 #endif 264