Coverage Report

Created: 2026-02-09 07:38

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/fluent-bit/src/flb_plugin_proxy.c
Line
Count
Source
1
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3
/*  Fluent Bit
4
 *  ==========
5
 *  Copyright (C) 2015-2026 The Fluent Bit Authors
6
 *
7
 *  Licensed under the Apache License, Version 2.0 (the "License");
8
 *  you may not use this file except in compliance with the License.
9
 *  You may obtain a copy of the License at
10
 *
11
 *      http://www.apache.org/licenses/LICENSE-2.0
12
 *
13
 *  Unless required by applicable law or agreed to in writing, software
14
 *  distributed under the License is distributed on an "AS IS" BASIS,
15
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
 *  See the License for the specific language governing permissions and
17
 *  limitations under the License.
18
 */
19
20
#include <stdio.h>
21
#include <stdlib.h>
22
#include <sys/types.h>
23
#include <sys/stat.h>
24
25
#include <monkey/mk_core.h>
26
#include <fluent-bit/flb_compat.h>
27
#include <fluent-bit/flb_info.h>
28
#include <fluent-bit/flb_log.h>
29
#include <fluent-bit/flb_mem.h>
30
#include <fluent-bit/flb_output.h>
31
#include <fluent-bit/flb_api.h>
32
#include <fluent-bit/flb_error.h>
33
#include <fluent-bit/flb_utils.h>
34
#include <fluent-bit/flb_plugin_proxy.h>
35
#include <fluent-bit/flb_input_log.h>
36
#include <fluent-bit/flb_custom.h>
37
38
/* Proxies */
39
#include "proxy/go/go.h"
40
41
0
#define PROXY_CALLBACK_TIME    1 /* 1 seconds */
42
43
static void proxy_cb_flush(struct flb_event_chunk *event_chunk,
44
                           struct flb_output_flush *out_flush,
45
                           struct flb_input_instance *i_ins,
46
                           void *out_context,
47
                           struct flb_config *config)
48
0
{
49
0
    int ret = FLB_ERROR;
50
0
    struct flb_plugin_proxy_context *ctx = out_context;
51
0
    (void) i_ins;
52
0
    (void) config;
53
54
0
#ifdef FLB_HAVE_PROXY_GO
55
0
    if (ctx->proxy->def->proxy == FLB_PROXY_GOLANG) {
56
0
        flb_trace("[GO] entering go_flush()");
57
0
        ret = proxy_go_output_flush(ctx,
58
0
                                    event_chunk->data,
59
0
                                    event_chunk->size,
60
0
                                    event_chunk->tag,
61
0
                                    flb_sds_len(event_chunk->tag));
62
0
    }
63
#else
64
    (void) ctx;
65
#endif
66
67
0
    if (ret != FLB_OK && ret != FLB_RETRY && ret != FLB_ERROR) {
68
0
        FLB_OUTPUT_RETURN(FLB_ERROR);
69
0
    }
70
71
0
    FLB_OUTPUT_RETURN(ret);
72
0
}
73
74
static int flb_proxy_input_cb_collect(struct flb_input_instance *ins,
75
                                      struct flb_config *config, void *in_context)
76
0
{
77
0
    int ret = FLB_OK;
78
0
    size_t len = 0;
79
0
    void *data = NULL;
80
0
    struct flb_plugin_input_proxy_context *ctx = (struct flb_plugin_input_proxy_context *) in_context;
81
82
0
#ifdef FLB_HAVE_PROXY_GO
83
0
    if (ctx->proxy->def->proxy == FLB_PROXY_GOLANG) {
84
0
        flb_trace("[GO] entering go_collect()");
85
0
        ret = proxy_go_input_collect(ctx, &data, &len);
86
87
0
        if (len == 0) {
88
0
            flb_trace("[GO] No logs are ingested");
89
0
            return -1;
90
0
        }
91
92
0
        if (ret == -1) {
93
0
            flb_errno();
94
0
            return -1;
95
0
        }
96
97
0
        flb_input_log_append(ins, NULL, 0, data, len);
98
99
0
        ret = proxy_go_input_cleanup(ctx, data);
100
0
        if (ret == -1) {
101
0
            flb_errno();
102
0
            return -1;
103
0
        }
104
0
    }
105
0
#endif
106
107
0
    return 0;
108
0
}
109
110
static int flb_proxy_input_cb_init(struct flb_input_instance *ins,
111
                                   struct flb_config *config, void *data)
112
0
{
113
0
    int ret = -1;
114
0
    struct flb_plugin_input_proxy_context *pc;
115
116
    /* Before to initialize for proxy, set the proxy instance reference */
117
0
    pc = (struct flb_plugin_input_proxy_context *)(ins->context);
118
119
    /* Before to initialize, set the instance reference */
120
0
    pc->proxy->instance = ins;
121
122
    /* Based on 'proxy', use the proper handler */
123
0
    if (pc->proxy->def->proxy == FLB_PROXY_GOLANG) {
124
0
#ifdef FLB_HAVE_PROXY_GO
125
0
        ret = proxy_go_input_init(pc->proxy);
126
127
0
        if (ret == -1) {
128
0
            flb_error("Could not initialize proxy for threaded input plugin");
129
0
            goto init_error;
130
0
        }
131
#else
132
        flb_error("Could not find initializing function on proxy for threaded input plugin");
133
        goto init_error;
134
#endif
135
0
    }
136
0
    else {
137
0
        flb_error("[proxy] unrecognized input proxy handler %i",
138
0
                  pc->proxy->def->proxy);
139
0
    }
140
141
    /* Set the context */
142
0
    flb_input_set_context(ins, pc);
143
144
    /* Collect upon data available on timer */
145
0
    ret = flb_input_set_collector_time(ins,
146
0
                                       flb_proxy_input_cb_collect,
147
0
                                       PROXY_CALLBACK_TIME, 0,
148
0
                                       config);
149
150
0
    if (ret == -1) {
151
0
        flb_error("Could not set collector for threaded proxy input plugin");
152
0
        goto init_error;
153
0
    }
154
0
    pc->coll_fd = ret;
155
156
0
    return ret;
157
158
0
init_error:
159
0
    flb_free(pc);
160
161
0
    return -1;
162
0
}
163
164
static void flb_proxy_input_cb_pause(void *data, struct flb_config *config)
165
0
{
166
0
    struct flb_plugin_input_proxy_context *ctx = data;
167
0
    struct flb_plugin_proxy *proxy = (ctx->proxy);
168
169
    /* pause */
170
0
    void (*cb_pause)(void);
171
172
0
    cb_pause = flb_plugin_proxy_symbol(proxy, "FLBPluginInputPause");
173
0
    if (cb_pause != NULL) {
174
0
        cb_pause();
175
0
    }
176
177
0
    flb_input_collector_pause(ctx->coll_fd, ctx->proxy->instance);
178
0
}
179
180
static void flb_proxy_input_cb_resume(void *data, struct flb_config *config)
181
0
{
182
0
    struct flb_plugin_input_proxy_context *ctx = data;
183
0
    struct flb_plugin_proxy *proxy = (ctx->proxy);
184
185
    /* resume */
186
0
    void (*cb_resume)(void);
187
188
0
    cb_resume = flb_plugin_proxy_symbol(proxy, "FLBPluginInputResume");
189
0
    if (cb_resume != NULL) {
190
0
        cb_resume();
191
0
    }
192
193
0
    flb_input_collector_resume(ctx->coll_fd, ctx->proxy->instance);
194
0
}
195
196
static void flb_plugin_proxy_destroy(struct flb_plugin_proxy *proxy);
197
198
static int flb_proxy_output_cb_exit(void *out_context, struct flb_config *config)
199
0
{
200
0
    struct flb_plugin_proxy_context *ctx = out_context;
201
0
    struct flb_plugin_proxy *proxy = (ctx->proxy);
202
    /* pre_exit (Golang plugin only) */
203
0
    void (*cb_pre_exit)(int);
204
205
0
    if (!out_context) {
206
0
        return 0;
207
0
    }
208
209
0
    cb_pre_exit = flb_plugin_proxy_symbol(proxy, "FLBPluginOutputPreExit");
210
0
    if (cb_pre_exit != NULL) {
211
0
        cb_pre_exit(config->shutdown_by_hot_reloading);
212
0
    }
213
214
0
    if (proxy->def->proxy == FLB_PROXY_GOLANG) {
215
0
#ifdef FLB_HAVE_PROXY_GO
216
0
        proxy_go_output_destroy(ctx);
217
0
#endif
218
0
    }
219
220
0
    flb_free(ctx);
221
0
    return 0;
222
0
}
223
224
static void flb_proxy_output_cb_destroy(struct flb_output_plugin *plugin)
225
0
{
226
0
    struct flb_plugin_proxy *proxy = (struct flb_plugin_proxy *) plugin->proxy;
227
    /* cleanup */
228
0
    void (*cb_unregister)(struct flb_plugin_proxy_def *def);
229
230
0
    cb_unregister = flb_plugin_proxy_symbol(proxy, "FLBPluginUnregister");
231
0
    if (cb_unregister != NULL) {
232
0
        cb_unregister(proxy->def);
233
0
    }
234
235
0
    if (plugin->name != NULL) {
236
0
        flb_free(plugin->name);
237
238
0
        plugin->name = NULL;
239
0
    }
240
241
0
    if (proxy->def->proxy == FLB_PROXY_GOLANG) {
242
0
#ifdef FLB_HAVE_PROXY_GO
243
0
proxy_go_output_unregister(proxy->data);
244
0
#endif
245
0
    }
246
247
0
    flb_plugin_proxy_destroy(proxy);
248
0
}
249
250
static int flb_proxy_input_cb_exit(void *in_context, struct flb_config *config)
251
0
{
252
0
    struct flb_plugin_input_proxy_context *ctx = in_context;
253
0
    struct flb_plugin_proxy *proxy = (ctx->proxy);
254
    /* pre_exit (Golang plugin only) */
255
0
    void (*cb_pre_exit)(int);
256
257
0
    if (!in_context) {
258
0
        return 0;
259
0
    }
260
261
0
    cb_pre_exit = flb_plugin_proxy_symbol(proxy, "FLBPluginInputPreExit");
262
0
    if (cb_pre_exit != NULL) {
263
0
        cb_pre_exit(config->shutdown_by_hot_reloading);
264
0
    }
265
266
0
    if (proxy->def->proxy == FLB_PROXY_GOLANG) {
267
0
#ifdef FLB_HAVE_PROXY_GO
268
0
        proxy_go_input_destroy(ctx);
269
0
#endif
270
0
    }
271
272
0
    flb_free(ctx);
273
0
    return 0;
274
0
}
275
276
static void flb_proxy_input_cb_destroy(struct flb_input_plugin *plugin)
277
0
{
278
0
    struct flb_plugin_proxy *proxy = (struct flb_plugin_proxy *) plugin->proxy;
279
    /* cleanup */
280
0
    void (*cb_unregister)(struct flb_plugin_proxy_def *def);
281
282
0
    cb_unregister = flb_plugin_proxy_symbol(proxy, "FLBPluginUnregister");
283
0
    if (cb_unregister != NULL) {
284
0
        cb_unregister(proxy->def);
285
0
    }
286
287
0
    if (plugin->name != NULL) {
288
0
        flb_free(plugin->name);
289
290
0
        plugin->name = NULL;
291
0
    }
292
293
0
    if (proxy->def->proxy == FLB_PROXY_GOLANG) {
294
0
#ifdef FLB_HAVE_PROXY_GO
295
0
        proxy_go_input_unregister(proxy->data);
296
0
#endif
297
0
    }
298
299
0
    flb_plugin_proxy_destroy(proxy);
300
0
}
301
302
static int flb_proxy_input_cb_pre_run(struct flb_input_instance *ins,
303
                                      struct flb_config *config, void *data)
304
0
{
305
0
    int ret = -1;
306
0
    struct flb_plugin_input_proxy_context *pc;
307
0
    struct flb_plugin_proxy *proxy;
308
309
0
    pc = (struct flb_plugin_input_proxy_context *)(ins->context);
310
0
    proxy = pc->proxy;
311
312
    /* pre_run */
313
0
    int (*cb_pre_run)(int);
314
315
0
    cb_pre_run = flb_plugin_proxy_symbol(proxy, "FLBPluginInputPreRun");
316
0
    if (cb_pre_run != NULL) {
317
0
        ret = cb_pre_run(config->enable_hot_reload);
318
0
    }
319
320
0
    return ret;
321
0
}
322
323
static int flb_proxy_output_cb_pre_run(void *out_context, struct flb_config *config)
324
0
{
325
0
    int ret = -1;
326
0
    struct flb_plugin_proxy_context *ctx = out_context;
327
0
    struct flb_plugin_proxy *proxy = (ctx->proxy);
328
329
0
    if (!out_context) {
330
0
        return 0;
331
0
    }
332
333
    /* pre_run */
334
0
    int (*cb_pre_run)(int);
335
336
0
    cb_pre_run = flb_plugin_proxy_symbol(proxy, "FLBPluginOutputPreRun");
337
0
    if (cb_pre_run != NULL) {
338
0
        ret = cb_pre_run(config->enable_hot_reload);
339
0
    }
340
341
0
    return ret;
342
0
}
343
344
int flb_proxy_output_cb_init(struct flb_output_instance *o_ins,
345
                             struct flb_config *config, void *data);
346
347
static int flb_proxy_register_output(struct flb_plugin_proxy *proxy,
348
                                     struct flb_plugin_proxy_def *def,
349
                                     struct flb_config *config)
350
0
{
351
0
    struct flb_output_plugin *out;
352
353
0
    out = flb_calloc(1, sizeof(struct flb_output_plugin));
354
0
    if (!out) {
355
0
        flb_errno();
356
0
        return -1;
357
0
    }
358
359
    /* Plugin registration */
360
0
    out->type  = FLB_OUTPUT_PLUGIN_PROXY;
361
0
    out->proxy = proxy;
362
0
    out->flags = def->flags;
363
0
    out->name  = flb_strdup(def->name);
364
365
0
    out->description = def->description;
366
0
    mk_list_add(&out->_head, &config->out_plugins);
367
368
    /*
369
     * Set proxy callbacks: external plugins which are not following
370
     * the core plugins specs, have a different callback approach, so
371
     * we put our proxy-middle callbacks to do the translation properly.
372
     */
373
0
    out->cb_init = flb_proxy_output_cb_init;
374
0
    out->cb_flush = proxy_cb_flush;
375
0
    out->cb_pre_run = flb_proxy_output_cb_pre_run;
376
0
    out->cb_exit = flb_proxy_output_cb_exit;
377
0
    out->cb_destroy = flb_proxy_output_cb_destroy;
378
0
    return 0;
379
0
}
380
381
static int flb_proxy_register_input(struct flb_plugin_proxy *proxy,
382
                                    struct flb_plugin_proxy_def *def,
383
                                    struct flb_config *config)
384
0
{
385
0
    struct flb_input_plugin *in;
386
387
0
    in = flb_calloc(1, sizeof(struct flb_input_plugin));
388
0
    if (!in) {
389
0
        flb_errno();
390
0
        return -1;
391
0
    }
392
393
    /* Plugin registration */
394
0
    in->type  = FLB_INPUT_PLUGIN_PROXY;
395
0
    in->proxy = proxy;
396
0
    in->flags = def->flags | FLB_INPUT_THREADED;
397
0
    in->name  = flb_strdup(def->name);
398
0
    in->description = def->description;
399
0
    mk_list_add(&in->_head, &config->in_plugins);
400
401
    /*
402
     * Set proxy callbacks: external plugins which are not following
403
     * the core plugins specs, have a different callback approach, so
404
     * we put our proxy-middle callbacks to do the translation properly.
405
     */
406
0
    in->cb_pre_run = flb_proxy_input_cb_pre_run;
407
0
    in->cb_init = flb_proxy_input_cb_init;
408
0
    in->cb_collect = flb_proxy_input_cb_collect;
409
0
    in->cb_flush_buf = NULL;
410
0
    in->cb_exit = flb_proxy_input_cb_exit;
411
0
    in->cb_destroy = flb_proxy_input_cb_destroy;
412
0
    in->cb_pause = flb_proxy_input_cb_pause;
413
0
    in->cb_resume = flb_proxy_input_cb_resume;
414
0
    return 0;
415
0
}
416
417
int flb_proxy_custom_cb_init(struct flb_custom_instance *c_ins,
418
                             struct flb_config *config, void *data);
419
420
static int flb_proxy_custom_cb_exit(void *custom_context,
421
                                    struct flb_config *config);
422
static void flb_proxy_custom_cb_destroy(struct flb_custom_plugin *plugin);
423
424
static int flb_proxy_register_custom(struct flb_plugin_proxy *proxy,
425
                                     struct flb_plugin_proxy_def *def,
426
                                     struct flb_config *config)
427
0
{
428
0
    struct flb_custom_plugin *custom;
429
430
0
    custom = flb_calloc(1, sizeof(struct flb_custom_plugin));
431
0
    if (!custom) {
432
0
        flb_errno();
433
0
        return -1;
434
0
    }
435
436
    /* Plugin registration */
437
0
    custom->type  = FLB_CUSTOM_PLUGIN_PROXY;
438
0
    custom->proxy = proxy;
439
0
    custom->flags = def->flags;
440
0
    custom->name  = flb_strdup(def->name);
441
0
    custom->description = def->description;
442
0
    mk_list_add(&custom->_head, &config->custom_plugins);
443
444
    /*
445
     * Set proxy callbacks: external plugins which are not following
446
     * the core plugins specs, have a different callback approach, so
447
     * we put our proxy-middle callbacks to do the translation properly.
448
     */
449
0
    custom->cb_init = flb_proxy_custom_cb_init;
450
0
    custom->cb_exit = flb_proxy_custom_cb_exit;
451
0
    custom->cb_destroy = flb_proxy_custom_cb_destroy;
452
0
    return 0;
453
0
}
454
455
void *flb_plugin_proxy_symbol(struct flb_plugin_proxy *proxy,
456
                              const char *symbol)
457
0
{
458
0
    void *s;
459
460
0
    dlerror();
461
0
    s = dlsym(proxy->dso_handler, symbol);
462
0
    if (dlerror() != NULL) {
463
0
        return NULL;
464
0
    }
465
0
    return s;
466
0
}
467
468
int flb_plugin_proxy_register(struct flb_plugin_proxy *proxy,
469
                              struct flb_config *config)
470
0
{
471
0
    int ret;
472
0
    int (*cb_register)(struct flb_plugin_proxy_def *);
473
0
    int (*cb_pre_register)(int);
474
0
    struct flb_plugin_proxy_def *def = proxy->def;
475
476
    /* Lookup the pre registration callback */
477
0
    cb_pre_register = flb_plugin_proxy_symbol(proxy, "FLBPluginPreRegister");
478
0
    if (cb_pre_register != NULL) {
479
        /* Prepare the registration if available */
480
0
        ret = cb_pre_register(config->hot_reloading);
481
0
        if (ret == -1) {
482
0
            return -1;
483
0
        }
484
0
    }
485
486
    /* Lookup the registration callback */
487
0
    cb_register = flb_plugin_proxy_symbol(proxy, "FLBPluginRegister");
488
0
    if (!cb_register) {
489
0
        return -1;
490
0
    }
491
492
    /*
493
     * Create a temporary definition used for registration. This definition
494
     * aims to be be populated by plugin in the registration phase with:
495
     *
496
     * - plugin type (or proxy type, e.g: Golang)
497
     * - plugin name
498
     * - plugin description
499
     */
500
501
    /* Do the registration */
502
0
    ret = cb_register(def);
503
0
    if (ret == -1) {
504
0
        flb_free(def);
505
0
        return -1;
506
0
    }
507
508
    /*
509
     * Each plugin proxy/type, have their own handler, based on the data
510
     * provided in the registration invoke the proper handler.
511
     */
512
0
    ret = -1;
513
0
    if (def->proxy == FLB_PROXY_GOLANG) {
514
0
#ifdef FLB_HAVE_PROXY_GO
515
0
        if (def->type == FLB_PROXY_OUTPUT_PLUGIN) {
516
0
            ret = proxy_go_output_register(proxy, def);
517
0
        }
518
0
        else if (def->type == FLB_PROXY_INPUT_PLUGIN) {
519
0
            ret = proxy_go_input_register(proxy, def);
520
0
        } 
521
0
        else if (def->type == FLB_PROXY_CUSTOM_PLUGIN) {
522
0
            ret = proxy_go_custom_register(proxy, def);
523
0
        }
524
0
#endif
525
0
    }
526
0
    if (ret == 0) {
527
        /*
528
         * We got a plugin that can do it job, now we need to create the
529
         * real link to the 'output' interface
530
         */
531
0
        if (def->type == FLB_PROXY_OUTPUT_PLUGIN) {
532
0
            flb_proxy_register_output(proxy, def, config);
533
0
        }
534
0
        else if (def->type == FLB_PROXY_INPUT_PLUGIN) {
535
0
            flb_proxy_register_input(proxy, def, config);
536
0
        }
537
0
        else if (def->type == FLB_PROXY_CUSTOM_PLUGIN) {
538
0
            flb_proxy_register_custom(proxy, def, config);
539
0
        }
540
0
    }
541
542
0
    return 0;
543
0
}
544
545
int flb_proxy_output_cb_init(struct flb_output_instance *o_ins,
546
                             struct flb_config *config, void *data)
547
0
{
548
0
    int ret = -1;
549
0
    struct flb_plugin_proxy_context *pc;
550
551
    /* Before to initialize for proxy, set the proxy instance reference */
552
0
    pc = (struct flb_plugin_proxy_context *)(o_ins->context);
553
554
    /* Before to initialize, set the instance reference */
555
0
    pc->proxy->instance = o_ins;
556
557
    /* Based on 'proxy', use the proper handler */
558
0
    if (pc->proxy->def->proxy == FLB_PROXY_GOLANG) {
559
0
#ifdef FLB_HAVE_PROXY_GO
560
0
        ret = proxy_go_output_init(pc->proxy);
561
0
#endif
562
0
    }
563
0
    else {
564
0
        flb_error("[proxy] unrecognized proxy handler %i",
565
0
                  pc->proxy->def->proxy);
566
0
    }
567
568
0
    if (ret == -1) {
569
0
        flb_error("[output] could not initialize '%s' plugin",
570
0
                  o_ins->p->name);
571
0
        return -1;
572
0
    }
573
574
    /* Multi-threading enabled if configured */
575
0
    ret = flb_output_enable_multi_threading(o_ins, config);
576
0
    if (ret == -1) {
577
0
        flb_error("[output] could not start thread pool for '%s' plugin",
578
0
                  o_ins->p->name);
579
0
        return -1;
580
0
    }
581
582
0
    return ret;
583
0
}
584
585
struct flb_plugin_proxy *flb_plugin_proxy_create(const char *dso_path, int type,
586
                                                 struct flb_config *config)
587
0
{
588
0
    void *handle;
589
0
    struct flb_plugin_proxy *proxy;
590
591
    /* Load shared library */
592
0
    handle = dlopen(dso_path, RTLD_LAZY);
593
0
    if (!handle) {
594
0
        flb_error("[proxy] error opening plugin %s: '%s'",
595
0
                  dso_path, dlerror());
596
0
        return NULL;
597
0
    }
598
599
    /* Proxy Context */
600
0
    proxy = flb_malloc(sizeof(struct flb_plugin_proxy));
601
0
    if (!proxy) {
602
0
        flb_errno();
603
0
        dlclose(handle);
604
0
        return NULL;
605
0
    }
606
607
    /* API Context */
608
0
    proxy->api = flb_api_create();
609
0
    if (!proxy->api) {
610
0
        dlclose(handle);
611
0
        flb_free(proxy);
612
0
        return NULL;
613
0
    }
614
615
0
    proxy->def = flb_malloc(sizeof(struct flb_plugin_proxy_def));
616
0
    if (!proxy->def) {
617
0
        flb_errno();
618
0
        dlclose(handle);
619
0
        flb_api_destroy(proxy->api);
620
0
        flb_free(proxy);
621
0
        return NULL;
622
0
    }
623
624
    /* Set fields and add it to the list */
625
0
    proxy->def->type        = type;
626
0
    proxy->dso_handler = handle;
627
0
    proxy->data        = NULL;
628
0
    mk_list_add(&proxy->_head, &config->proxies);
629
630
    /* Register plugin */
631
0
    flb_plugin_proxy_register(proxy, config);
632
633
0
    return proxy;
634
0
}
635
636
static void flb_plugin_proxy_destroy(struct flb_plugin_proxy *proxy)
637
0
{
638
0
    flb_free(proxy->def);
639
0
    flb_api_destroy(proxy->api);
640
0
    dlclose(proxy->dso_handler);
641
0
    mk_list_del(&proxy->_head);
642
0
    flb_free(proxy);
643
0
}
644
645
int flb_plugin_proxy_set(struct flb_plugin_proxy_def *def, int type,
646
                         int proxy, char *name, char *description)
647
0
{
648
0
    def->type  = type;
649
0
    def->proxy = proxy;
650
0
    def->name  = flb_strdup(name);
651
0
    def->description = flb_strdup(description);
652
653
0
    return 0;
654
0
}
655
656
int flb_proxy_custom_cb_init(struct flb_custom_instance *c_ins,
657
                             struct flb_config *config, void *data)
658
0
{
659
0
    int ret = -1;
660
0
    struct flb_plugin_proxy_context *pc;
661
0
    struct flb_plugin_proxy *proxy;
662
663
0
    pc = (struct flb_plugin_proxy_context *)(c_ins->context);
664
0
    proxy = pc->proxy;
665
666
    /* Before to initialize, set the instance reference */
667
0
    pc->proxy->instance = c_ins;
668
669
0
    if (proxy->def->proxy == FLB_PROXY_GOLANG) {
670
0
#ifdef FLB_HAVE_PROXY_GO
671
0
        ret = proxy_go_custom_init(proxy);
672
0
#endif
673
0
    }
674
675
0
    if (ret == -1) {
676
0
        flb_error("[custom] could not initialize '%s' plugin",
677
0
                  c_ins->p->name);
678
0
        return -1;
679
0
    }
680
681
0
    return 0;
682
0
}
683
684
int flb_proxy_custom_cb_exit(void *custom_context, 
685
                             struct flb_config *config)
686
0
{
687
0
    int ret = -1;
688
0
    struct flb_plugin_proxy_context *ctx = custom_context;
689
0
    struct flb_plugin_proxy *proxy = (ctx->proxy);
690
0
    if (!custom_context) {
691
0
        return ret;
692
0
    }
693
694
0
    if (proxy->def->proxy == FLB_PROXY_GOLANG) {
695
0
#ifdef FLB_HAVE_PROXY_GO
696
0
        ret = proxy_go_custom_destroy(ctx);
697
0
#endif
698
0
    }
699
700
0
    flb_free(ctx);
701
0
    return ret;
702
0
}
703
704
static void flb_proxy_custom_cb_destroy(struct flb_custom_plugin *plugin)
705
0
{
706
0
    struct flb_plugin_proxy *proxy = (struct flb_plugin_proxy *) plugin->proxy;
707
708
0
    if (plugin->name != NULL) {
709
0
        flb_free(plugin->name);
710
711
0
        plugin->name = NULL;
712
0
    }
713
714
0
    if (proxy->def->proxy == FLB_PROXY_GOLANG) {
715
0
#ifdef FLB_HAVE_PROXY_GO
716
0
        proxy_go_custom_unregister(proxy->data);
717
0
#endif
718
0
    }
719
720
0
    flb_plugin_proxy_destroy(proxy);
721
0
}