blob: 8d6d4bef33e221d186be0241c6622d6051c460a3 [file] [log] [blame]
Thierry FOURNIER4aec0a42018-02-23 11:42:57 +01001/* Main SPOA server includes
2 *
3 * Copyright 2016 HAProxy Technologies, Christopher Faulet <cfaulet@haproxy.com>
4 * Copyright 2018 OZON / Thierry Fournier <thierry.fournier@ozon.io>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11#ifndef __SPOA_H__
12#define __SPOA_H__
13
Thierry FOURNIER880d7e12018-02-25 10:54:56 +010014#include <pthread.h>
Thierry FOURNIER4aec0a42018-02-23 11:42:57 +010015#include <stdbool.h>
16#include <stdint.h>
17#include <netinet/in.h>
Thierry FOURNIER880d7e12018-02-25 10:54:56 +010018#include <sys/time.h>
Thierry FOURNIER4aec0a42018-02-23 11:42:57 +010019
Bertrand Jacquinae2132c2020-08-24 19:21:30 +000020#ifndef MAX_FRAME_SIZE
Thierry FOURNIER4aec0a42018-02-23 11:42:57 +010021#define MAX_FRAME_SIZE 16384
Bertrand Jacquinae2132c2020-08-24 19:21:30 +000022#endif
23
Daniel Corbett58978672019-06-10 21:01:32 -040024#define SPOP_VERSION "2.0"
Thierry FOURNIER4aec0a42018-02-23 11:42:57 +010025#define SPOA_CAPABILITIES ""
26
Daniel Corbett4e0fa552019-06-11 09:46:27 -040027/* Flags set on the SPOE frame */
28#define SPOE_FRM_FL_FIN 0x00000001
29
Thierry FOURNIER4aec0a42018-02-23 11:42:57 +010030/* All supported data types */
31enum spoe_data_type {
32 SPOE_DATA_T_NULL = 0,
33 SPOE_DATA_T_BOOL,
34 SPOE_DATA_T_INT32,
35 SPOE_DATA_T_UINT32,
36 SPOE_DATA_T_INT64,
37 SPOE_DATA_T_UINT64,
38 SPOE_DATA_T_IPV4,
39 SPOE_DATA_T_IPV6,
40 SPOE_DATA_T_STR,
41 SPOE_DATA_T_BIN,
42 SPOE_DATA_TYPES
43};
44
45/* Scopes used for variables set by agents. It is a way to be agnotic to vars
46 * scope. */
47enum spoe_vars_scope {
48 SPOE_SCOPE_PROC = 0, /* <=> SCOPE_PROC */
49 SPOE_SCOPE_SESS, /* <=> SCOPE_SESS */
50 SPOE_SCOPE_TXN, /* <=> SCOPE_TXN */
51 SPOE_SCOPE_REQ, /* <=> SCOPE_REQ */
52 SPOE_SCOPE_RES, /* <=> SCOPE_RES */
53};
54
55struct worker {
56 unsigned int id;
57 char buf[MAX_FRAME_SIZE];
58 unsigned int len;
59 unsigned int size;
60 int status_code;
61 unsigned int stream_id;
62 unsigned int frame_id;
63 bool healthcheck;
Thierry FOURNIERfbd38242018-02-23 18:24:10 +010064 char ack[MAX_FRAME_SIZE];
65 unsigned int ack_len;
Thierry FOURNIER4aec0a42018-02-23 11:42:57 +010066};
67
68struct chunk {
69 char *str; /* beginning of the string itself. Might not be 0-terminated */
70 int len; /* current size of the string from first to last char */
71};
72
73union spoe_value {
74 bool boolean; /* use for boolean */
75 int32_t sint32; /* used for signed 32bits integers */
76 uint32_t uint32; /* used for signed 32bits integers */
77 int32_t sint64; /* used for signed 64bits integers */
78 uint32_t uint64; /* used for signed 64bits integers */
79 struct in_addr ipv4; /* used for ipv4 addresses */
80 struct in6_addr ipv6; /* used for ipv6 addresses */
81 struct chunk buffer; /* used for char strings or buffers */
82};
83
84/* Used to store sample constant */
85struct spoe_data {
86 enum spoe_data_type type; /* SPOE_DATA_T_* */
87 union spoe_value u; /* spoe data value */
88};
89
Thierry FOURNIER64eaa332018-02-23 14:58:40 +010090struct spoe_kv {
91 struct chunk name;
92 struct spoe_data value;
93};
94
95struct ps {
96 struct ps *next;
97 char *ext;
98 int (*init_worker)(struct worker *w);
Thierry FOURNIER892f6642018-02-23 14:27:05 +010099 int (*exec_message)(struct worker *w, void *ref, int nargs, struct spoe_kv *args);
Thierry FOURNIER8b9a73b2018-02-23 15:12:55 +0100100 int (*load_file)(struct worker *w, const char *file);
Thierry FOURNIER64eaa332018-02-23 14:58:40 +0100101};
102
Thierry FOURNIER892f6642018-02-23 14:27:05 +0100103struct ps_message {
104 struct ps_message *next;
105 const char *name;
106 struct ps *ps;
107 void *ref;
108};
109
Thierry FOURNIER880d7e12018-02-25 10:54:56 +0100110extern bool debug;
111extern pthread_key_t worker_id;
112
Thierry FOURNIER64eaa332018-02-23 14:58:40 +0100113void ps_register(struct ps *ps);
Thierry FOURNIER892f6642018-02-23 14:27:05 +0100114void ps_register_message(struct ps *ps, const char *name, void *ref);
Thierry FOURNIER64eaa332018-02-23 14:58:40 +0100115
Thierry FOURNIERfbd38242018-02-23 18:24:10 +0100116int set_var_null(struct worker *w,
117 const char *name, int name_len,
118 unsigned char scope);
119int set_var_bool(struct worker *w,
120 const char *name, int name_len,
121 unsigned char scope, bool value);
122int set_var_uint32(struct worker *w,
123 const char *name, int name_len,
124 unsigned char scope, uint32_t value);
125int set_var_int32(struct worker *w,
126 const char *name, int name_len,
127 unsigned char scope, int32_t value);
128int set_var_uint64(struct worker *w,
129 const char *name, int name_len,
130 unsigned char scope, uint64_t value);
131int set_var_int64(struct worker *w,
132 const char *name, int name_len,
133 unsigned char scope, int64_t value);
134int set_var_ipv4(struct worker *w,
135 const char *name, int name_len,
136 unsigned char scope,
137 struct in_addr *ipv4);
138int set_var_ipv6(struct worker *w,
139 const char *name, int name_len,
140 unsigned char scope,
141 struct in6_addr *ipv6);
142int set_var_string(struct worker *w,
143 const char *name, int name_len,
144 unsigned char scope,
145 const char *str, int strlen);
146int set_var_bin(struct worker *w,
147 const char *name, int name_len,
148 unsigned char scope,
149 const char *str, int strlen);
150
Thierry FOURNIER880d7e12018-02-25 10:54:56 +0100151#define LOG(fmt, args...) \
152 do { \
153 struct timeval now; \
154 int wid = *((int*)pthread_getspecific(worker_id)); \
155 \
156 gettimeofday(&now, NULL); \
157 fprintf(stderr, "%ld.%06ld [%02d] " fmt "\n", \
158 now.tv_sec, now.tv_usec, wid, ##args); \
159 } while (0)
160
161#define DEBUG(x...) \
162 do { \
163 if (debug) \
164 LOG(x); \
165 } while (0)
166
Thierry FOURNIER4aec0a42018-02-23 11:42:57 +0100167#endif /* __SPOA_H__ */