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