blob: 8f912e435fe2f09a0dab9ed8bf4669922ff17683 [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
20#define MAX_FRAME_SIZE 16384
Daniel Corbett58978672019-06-10 21:01:32 -040021#define SPOP_VERSION "2.0"
Thierry FOURNIER4aec0a42018-02-23 11:42:57 +010022#define SPOA_CAPABILITIES ""
23
Daniel Corbett4e0fa552019-06-11 09:46:27 -040024/* Flags set on the SPOE frame */
25#define SPOE_FRM_FL_FIN 0x00000001
26
Thierry FOURNIER4aec0a42018-02-23 11:42:57 +010027/* All supported data types */
28enum spoe_data_type {
29 SPOE_DATA_T_NULL = 0,
30 SPOE_DATA_T_BOOL,
31 SPOE_DATA_T_INT32,
32 SPOE_DATA_T_UINT32,
33 SPOE_DATA_T_INT64,
34 SPOE_DATA_T_UINT64,
35 SPOE_DATA_T_IPV4,
36 SPOE_DATA_T_IPV6,
37 SPOE_DATA_T_STR,
38 SPOE_DATA_T_BIN,
39 SPOE_DATA_TYPES
40};
41
42/* Scopes used for variables set by agents. It is a way to be agnotic to vars
43 * scope. */
44enum spoe_vars_scope {
45 SPOE_SCOPE_PROC = 0, /* <=> SCOPE_PROC */
46 SPOE_SCOPE_SESS, /* <=> SCOPE_SESS */
47 SPOE_SCOPE_TXN, /* <=> SCOPE_TXN */
48 SPOE_SCOPE_REQ, /* <=> SCOPE_REQ */
49 SPOE_SCOPE_RES, /* <=> SCOPE_RES */
50};
51
52struct worker {
53 unsigned int id;
54 char buf[MAX_FRAME_SIZE];
55 unsigned int len;
56 unsigned int size;
57 int status_code;
58 unsigned int stream_id;
59 unsigned int frame_id;
60 bool healthcheck;
Thierry FOURNIERfbd38242018-02-23 18:24:10 +010061 char ack[MAX_FRAME_SIZE];
62 unsigned int ack_len;
Thierry FOURNIER4aec0a42018-02-23 11:42:57 +010063};
64
65struct chunk {
66 char *str; /* beginning of the string itself. Might not be 0-terminated */
67 int len; /* current size of the string from first to last char */
68};
69
70union spoe_value {
71 bool boolean; /* use for boolean */
72 int32_t sint32; /* used for signed 32bits integers */
73 uint32_t uint32; /* used for signed 32bits integers */
74 int32_t sint64; /* used for signed 64bits integers */
75 uint32_t uint64; /* used for signed 64bits integers */
76 struct in_addr ipv4; /* used for ipv4 addresses */
77 struct in6_addr ipv6; /* used for ipv6 addresses */
78 struct chunk buffer; /* used for char strings or buffers */
79};
80
81/* Used to store sample constant */
82struct spoe_data {
83 enum spoe_data_type type; /* SPOE_DATA_T_* */
84 union spoe_value u; /* spoe data value */
85};
86
Thierry FOURNIER64eaa332018-02-23 14:58:40 +010087struct spoe_kv {
88 struct chunk name;
89 struct spoe_data value;
90};
91
92struct ps {
93 struct ps *next;
94 char *ext;
95 int (*init_worker)(struct worker *w);
Thierry FOURNIER892f6642018-02-23 14:27:05 +010096 int (*exec_message)(struct worker *w, void *ref, int nargs, struct spoe_kv *args);
Thierry FOURNIER8b9a73b2018-02-23 15:12:55 +010097 int (*load_file)(struct worker *w, const char *file);
Thierry FOURNIER64eaa332018-02-23 14:58:40 +010098};
99
Thierry FOURNIER892f6642018-02-23 14:27:05 +0100100struct ps_message {
101 struct ps_message *next;
102 const char *name;
103 struct ps *ps;
104 void *ref;
105};
106
Thierry FOURNIER880d7e12018-02-25 10:54:56 +0100107extern bool debug;
108extern pthread_key_t worker_id;
109
Thierry FOURNIER64eaa332018-02-23 14:58:40 +0100110void ps_register(struct ps *ps);
Thierry FOURNIER892f6642018-02-23 14:27:05 +0100111void ps_register_message(struct ps *ps, const char *name, void *ref);
Thierry FOURNIER64eaa332018-02-23 14:58:40 +0100112
Thierry FOURNIERfbd38242018-02-23 18:24:10 +0100113int set_var_null(struct worker *w,
114 const char *name, int name_len,
115 unsigned char scope);
116int set_var_bool(struct worker *w,
117 const char *name, int name_len,
118 unsigned char scope, bool value);
119int set_var_uint32(struct worker *w,
120 const char *name, int name_len,
121 unsigned char scope, uint32_t value);
122int set_var_int32(struct worker *w,
123 const char *name, int name_len,
124 unsigned char scope, int32_t value);
125int set_var_uint64(struct worker *w,
126 const char *name, int name_len,
127 unsigned char scope, uint64_t value);
128int set_var_int64(struct worker *w,
129 const char *name, int name_len,
130 unsigned char scope, int64_t value);
131int set_var_ipv4(struct worker *w,
132 const char *name, int name_len,
133 unsigned char scope,
134 struct in_addr *ipv4);
135int set_var_ipv6(struct worker *w,
136 const char *name, int name_len,
137 unsigned char scope,
138 struct in6_addr *ipv6);
139int set_var_string(struct worker *w,
140 const char *name, int name_len,
141 unsigned char scope,
142 const char *str, int strlen);
143int set_var_bin(struct worker *w,
144 const char *name, int name_len,
145 unsigned char scope,
146 const char *str, int strlen);
147
Thierry FOURNIER880d7e12018-02-25 10:54:56 +0100148#define LOG(fmt, args...) \
149 do { \
150 struct timeval now; \
151 int wid = *((int*)pthread_getspecific(worker_id)); \
152 \
153 gettimeofday(&now, NULL); \
154 fprintf(stderr, "%ld.%06ld [%02d] " fmt "\n", \
155 now.tv_sec, now.tv_usec, wid, ##args); \
156 } while (0)
157
158#define DEBUG(x...) \
159 do { \
160 if (debug) \
161 LOG(x); \
162 } while (0)
163
Thierry FOURNIER4aec0a42018-02-23 11:42:57 +0100164#endif /* __SPOA_H__ */