syslog-ng source
transport-stack.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2002-2018 Balabit
3  * Copyright (c) 2018 Laszlo Budai <laszlo.budai@balabit.com>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18  *
19  * As an additional exemption you are allowed to compile & link against the
20  * OpenSSL libraries as published by the OpenSSL project. See the file
21  * COPYING for details.
22  *
23  */
24 
25 #ifndef TRANSPORT_STACK_H_INCLUDED
26 #define TRANSPORT_STACK_H_INCLUDED
27 
28 #include "transport/logtransport.h"
29 
30 typedef struct _LogTransportFactory LogTransportFactory;
31 
32 typedef enum
33 {
44 
46 {
47  gint index;
48  LogTransport *(*construct_transport)(const LogTransportFactory *self, LogTransportStack *stack);
49  void (*free_fn)(LogTransportFactory *self);
50 };
51 
52 static inline LogTransport *
53 log_transport_factory_construct_transport(const LogTransportFactory *self, LogTransportStack *stack)
54 {
55  g_assert(self->construct_transport);
56 
57  LogTransport *transport = self->construct_transport(self, stack);
58 
59  return transport;
60 }
61 
62 static inline void
63 log_transport_factory_free(LogTransportFactory *self)
64 {
65  if (self->free_fn)
66  self->free_fn(self);
67  g_free(self);
68 }
69 
70 void log_transport_factory_init_instance(LogTransportFactory *self, LogTransportIndex index);
71 
72 
73 /* LogTransportStack
74  *
75  * This is a struct embedded into a LogProto instance and represents a
76  * combination of LogTransport instances that somehow work together.
77  * LogTransportStack allows "switching" between LogTransport instances so we
78  * can implement changes on the transport layer mid stream. Such a change
79  * would be for example the switch to the TLS transport after a STARTTLS.
80  *
81  * It is also possible to stack log transports, e.g. LogTransportAdapter
82  * would add some further processing on top of another. A use case here is
83  * the HAProxy implementation, which reads the proxy header from
84  * LogTransportSocket, processes it and then allows the LogProto
85  * implementation to interact with the peer.
86  *
87  * LogTransportStack ensures that all LogTransport instances are freed at
88  * the same time, so there's no need to keep references around. It also
89  * manages the closing of the underlying file descriptor.
90  *
91  * Right now, transports are identified using the LOG_TRANSPORT_XXXX enum,
92  * meaning that any new "layer" we can potentially push to the transport
93  * stack will need a new element in the enumeration. Although this is a bit
94  * of a layering violation and prevents new LogTransport implementations
95  * coming from plugins, it is only an easy to change implementation detail,
96  * which is perfectly fine with all transports provided by the core itself.
97  *
98  * A layer in the stack is either instantiated by the caller and pushed to
99  * the stack _OR_ it is instantiated automatically by LogTransportStack
100  * using the LogTransportFactory interface.
101  */
103 {
105  gint fd;
109 };
110 
111 static inline LogTransportFactory *
112 log_transport_stack_get_transport_factory(LogTransportStack *self, gint index)
113 {
114  g_assert(index < LOG_TRANSPORT__MAX);
115 
116  return self->transport_factories[index];
117 }
118 
119 static inline LogTransport *
120 log_transport_stack_get_transport(LogTransportStack *self, gint index)
121 {
122  g_assert(index < LOG_TRANSPORT__MAX);
123 
124  return self->transports[index];
125 }
126 
127 static inline LogTransport *
128 log_transport_stack_get_or_create_transport(LogTransportStack *self, gint index)
129 {
130  LogTransport *transport = log_transport_stack_get_transport(self, index);
131 
132  if (transport)
133  return transport;
134 
135  if (self->transport_factories[index])
136  {
137  self->transports[index] = log_transport_factory_construct_transport(self->transport_factories[index], self);
138  log_transport_assign_to_stack(self->transports[index], self);
139  return self->transports[index];
140  }
141  return NULL;
142 }
143 
144 static inline LogTransport *
145 log_transport_stack_get_active(LogTransportStack *self)
146 {
147  // TODO - Change it to log_transport_stack_get_transport after checking call sites
148  return log_transport_stack_get_or_create_transport(self, self->active_transport);
149 }
150 
151 static inline gboolean
152 log_transport_stack_poll_prepare(LogTransportStack *self, GIOCondition *cond)
153 {
154  LogTransport *transport = log_transport_stack_get_active(self);
155  return log_transport_poll_prepare(transport, cond);
156 }
157 
158 static inline LogTransportIOCond
159 log_transport_stack_get_io_requirement(LogTransportStack *self)
160 {
161  LogTransport *transport = log_transport_stack_get_active(self);
162  return log_transport_get_io_requirement(transport);
163 }
164 
165 static inline gssize
166 log_transport_stack_write(LogTransportStack *self, const gpointer buf, gsize count)
167 {
168  LogTransport *transport = log_transport_stack_get_active(self);
169  return log_transport_write(transport, buf, count);
170 }
171 
172 static inline gssize
173 log_transport_stack_writev(LogTransportStack *self, struct iovec *iov, gint iov_count)
174 {
175  LogTransport *transport = log_transport_stack_get_active(self);
176  return log_transport_writev(transport, iov, iov_count);
177 }
178 
179 static inline gssize
180 log_transport_stack_read(LogTransportStack *self, gpointer buf, gsize count, LogTransportAuxData *aux)
181 {
182  LogTransport *transport = log_transport_stack_get_active(self);
183  log_transport_aux_data_copy(aux, &self->aux_data);
184  return log_transport_read(transport, buf, count, aux);
185 }
186 
187 static inline gssize
188 log_transport_stack_read_ahead(LogTransportStack *self, gpointer buf, gsize count, gboolean *moved_forward)
189 {
190  LogTransport *transport = log_transport_stack_get_active(self);
191  return log_transport_read_ahead(transport, buf, count, moved_forward);
192 }
193 
194 void log_transport_stack_add_factory(LogTransportStack *self, LogTransportFactory *);
195 void log_transport_stack_add_transport(LogTransportStack *self, gint index, LogTransport *);
196 gboolean log_transport_stack_switch(LogTransportStack *self, gint index);
197 void log_transport_stack_move(LogTransportStack *self, LogTransportStack *other);
198 void log_transport_stack_shutdown(LogTransportStack *self);
199 
200 void log_transport_stack_init(LogTransportStack *self, LogTransport *initial_transport);
201 void log_transport_stack_deinit(LogTransportStack *self);
202 
203 #endif
gssize log_transport_read_ahead(LogTransport *self, gpointer buf, gsize buflen, gboolean *moved_forward)
Definition: logtransport.c:83
LogTransportIOCond
Definition: logtransport.h:32
#define self
Definition: rcptid.c:38
Definition: transport-aux-data.h:30
Definition: transport-stack.h:46
void(* free_fn)(LogTransportFactory *self)
Definition: transport-stack.h:49
gint index
Definition: transport-stack.h:47
Definition: transport-stack.h:103
LogTransportAuxData aux_data
Definition: transport-stack.h:108
LogTransport * transports[LOG_TRANSPORT__MAX]
Definition: transport-stack.h:106
gint active_transport
Definition: transport-stack.h:104
gint fd
Definition: transport-stack.h:105
LogTransportFactory * transport_factories[LOG_TRANSPORT__MAX]
Definition: transport-stack.h:107
LogTransportAuxData * aux
Definition: test_aux_data.c:28
void log_transport_stack_shutdown(LogTransportStack *self)
Definition: transport-stack.c:117
LogTransportIndex
Definition: transport-stack.h:33
@ LOG_TRANSPORT__MAX
Definition: transport-stack.h:42
@ LOG_TRANSPORT_INITIAL
Definition: transport-stack.h:34
@ LOG_TRANSPORT_TLS
Definition: transport-stack.h:37
@ LOG_TRANSPORT_GZIP
Definition: transport-stack.h:39
@ LOG_TRANSPORT_SOCKET
Definition: transport-stack.h:36
@ LOG_TRANSPORT_FD
Definition: transport-stack.h:35
@ LOG_TRANSPORT_ZLIB
Definition: transport-stack.h:40
@ LOG_TRANSPORT_NONE
Definition: transport-stack.h:41
@ LOG_TRANSPORT_HAPROXY
Definition: transport-stack.h:38
void log_transport_stack_deinit(LogTransportStack *self)
Definition: transport-stack.c:135
void log_transport_stack_init(LogTransportStack *self, LogTransport *initial_transport)
Definition: transport-stack.c:125
void log_transport_stack_move(LogTransportStack *self, LogTransportStack *other)
Definition: transport-stack.c:90
void log_transport_stack_add_factory(LogTransportStack *self, LogTransportFactory *)
Definition: transport-stack.c:38
gboolean log_transport_stack_switch(LogTransportStack *self, gint index)
Definition: transport-stack.c:58
void log_transport_stack_add_transport(LogTransportStack *self, gint index, LogTransport *)
Definition: transport-stack.c:46
void log_transport_factory_init_instance(LogTransportFactory *self, LogTransportIndex index)
Definition: transport-stack.c:31