forked from skupperproject/skupper-router
-
Notifications
You must be signed in to change notification settings - Fork 0
/
protocol_adaptor.h
968 lines (865 loc) · 37.4 KB
/
protocol_adaptor.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
#ifndef __protocol_adaptor_h__
#define __protocol_adaptor_h__ 1
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#include "qpid/dispatch/delivery_state.h"
#include "qpid/dispatch/policy_spec.h"
#include "qpid/dispatch/router_core.h"
#include "qpid/dispatch/io_module.h"
typedef struct qdr_protocol_adaptor_t qdr_protocol_adaptor_t;
typedef struct qdr_connection_t qdr_connection_t;
typedef struct qdr_link_t qdr_link_t;
typedef struct qdr_delivery_t qdr_delivery_t;
typedef struct qdr_terminus_t qdr_terminus_t;
typedef struct qdr_connection_info_t qdr_connection_info_t;
/**
* Data flow direction with respect to the router
*/
typedef enum {
QD_INCOMING,
QD_OUTGOING
} qd_direction_t;
/**
* Session Class
*
* Used when creating new links from the router. A connection maintains a set
* of sessions over which links can be created. The session class indicates
* which session to use when creating a link.
*/
typedef enum {
QD_SSN_ENDPOINT, ///< client data links
QD_SSN_ROUTER_CONTROL, ///< router protocol
QD_SSN_ROUTER_DATA_PRI_0, ///< inter-router data links (by priority)
QD_SSN_ROUTER_DATA_PRI_1,
QD_SSN_ROUTER_DATA_PRI_2,
QD_SSN_ROUTER_DATA_PRI_3,
QD_SSN_ROUTER_DATA_PRI_4,
QD_SSN_ROUTER_DATA_PRI_5,
QD_SSN_ROUTER_DATA_PRI_6,
QD_SSN_ROUTER_DATA_PRI_7,
QD_SSN_ROUTER_DATA_PRI_8,
QD_SSN_ROUTER_DATA_PRI_9,
QD_SSN_CORE_ENDPOINT, ///< core subscriptions
QD_SSN_LINK_ROUTE, ///< link routes
QD_SSN_LINK_STREAMING, ///< link dedicated to streaming messages
QD_SSN_CLASS_COUNT
} qd_session_class_t;
/**
******************************************************************************
* Callback function definitions
******************************************************************************
*/
/**
* qdr_connection_activate_t callback
*
* Activate a connection with pending work from the core to ensure it will be processed by
* the proactor: the core has deliveries on links, disposition updates on deliveries, or
* flow updates to be sent across the connection.
*
* IMPORTANT: This function will be invoked on the core thread. It must never block,
* delay, or do any lengthy computation.
*
* @param context The context supplied when the callback was registered
* @param conn The connection object to be activated
*/
typedef void (*qdr_connection_activate_t) (void *context, qdr_connection_t *conn);
/**
* qdr_link_first_attach_t callback
*
* This function is invoked when the core requires that a new link be attached over a
* connection. Such a link is either being initiated from the core or is the propagation
* of a link route from an originator somewhere in the network.
*
* @param context The context supplied when the callback was registered
* @param conn The connection over which the first attach is to be sent
* @param link The link object for the new link
* @param source The source terminus for the attach
* @param target The target terminus for the attach
* @param ssn_class The session class to be used to allocate this link to a session
*/
typedef void (*qdr_link_first_attach_t) (void *context,
qdr_connection_t *conn,
qdr_link_t *link,
qdr_terminus_t *source,
qdr_terminus_t *target,
qd_session_class_t ssn_class);
/**
* qdr_link_second_attach_t callback
*
* This function is invoked when the core is responding to an incoming attach from an
* external container. The function must send the responding (second) attach to the
* remote container to complete the attachment of the link.
*
* @param context The context supplied when the callback was registered
* @param link The link being attached
* @param source The source terminus for the attach
* @param target The target terminus for the attach
*/
typedef void (*qdr_link_second_attach_t) (void *context,
qdr_link_t *link,
qdr_terminus_t *source,
qdr_terminus_t *target);
/**
* qdr_link_detach_t callback
*
* A DETACH performative must be sent for a link that is being closed or detached.
*
* @param context The context supplied when the callback was registered
* @param link The link being detached
* @param error Error record if the detach is the result of an error condition, null otherwise
* @param first True if this is the first detach (i.e. initiated outbound), False if this is the
* the response to a remotely initiated detach
*/
typedef void (*qdr_link_detach_t) (void *context, qdr_link_t *link, qdr_error_t *error, bool first);
/**
* qdr_link_flow_t callback
*
* Credit is being issued for an incoming link. Credit is issued incrementally, being added
* to credit may have been issued in the past.
*
* @param context The context supplied when the callback was registered
* @param link The link for which credit is being issued
* @param credit The number of new credits being issued to the link
*/
typedef void (*qdr_link_flow_t) (void *context, qdr_link_t *link, int credit);
/**
* qdr_link_offer_t callback
*
* This function is invoked when the core wishes to inform the remote terminus of an outgoing link
* that it is willing and ready to transfer a certain number of deliveries over that link.
*
* @param context The context supplied when the callback was registered
* @param link The link being affected
* @param delivery_count The number of deliveries available to be sent over this link
*/
typedef void (*qdr_link_offer_t) (void *context, qdr_link_t *link, int delivery_count);
/**
* qdr_link_drained_t callback
*
* This function is invoked when the core wishes to inform the remote terminus of an outgoing link
* that it has drained its outgoing deliveries and removed any residual credit.
*
* @param context The context supplied when the callback was registered
* @param link The link being affected
*/
typedef void (*qdr_link_drained_t) (void *context, qdr_link_t *link);
/**
* qdr_link_drain_t callback
*
* This function is invoked when the core wishes to inform the remote terminus of a link
* that the drain mode of the link has changed.
*
* @param context The context supplied when the callback was registered
* @param link The link being affected
* @param mode True for enabling drain mode, False for disabling drain mode
*/
typedef void (*qdr_link_drain_t) (void *context, qdr_link_t *link, bool mode);
/**
* qdr_link_push_t callback
*
* The core invokes this function when it wishes to transfer deliveries on an outgoing link.
* This function, in turn, calls qdr_link_process_deliveries with the desired number of
* deliveries (up to limit) that should be transferred from the core. Typically, this
* function will call qdr_link_process_deliveries with MIN(limit, available-credit).
*
* @param context The context supplied when the callback was registered
* @param link The link over which deliveries should be transferred
* @param limit The maximum number of deliveries that should be transferred
* @return The number of deliveries transferred
*/
typedef int (*qdr_link_push_t) (void *context, qdr_link_t *link, int limit);
extern const uint64_t QD_DELIVERY_MOVED_TO_NEW_LINK;
/**
* qdr_link_deliver_t callback
*
* This function is invoked by the core during the execution of qdr_link_process_deliveries. There
* is one invocation for each delivery to be transferred. If this function returns a non-zero
* disposition, the core will settle the delivery with that disposition back to the sender.
*
* @param context The context supplied when the callback was registered
* @param link The link over which deliveries should be transferred
* @param delivery The delivery (which contains the message) to be transferred
* @param settled True iff the delivery is already settled
* @return The disposition of the delivery to be sent back to the sender, or 0 if no disposition
*/
typedef uint64_t (*qdr_link_deliver_t) (void *context, qdr_link_t *link, qdr_delivery_t *delivery, bool settled);
/**
* qdr_link_get_credit_t callback
*
* Query a link for the current amount of available credit.
*
* @param context The context supplied when the callback was registered
* @param link The link being queried
* @return The number of credits available on this link
*/
typedef int (*qdr_link_get_credit_t) (void *context, qdr_link_t *link);
/**
* qdr_delivery_update_t callback
*
* This function is invoked by the core when a delivery's disposition and settlement are being
* changed. This function must send the updated delivery state to the remote terminus.
*
* @param context The context supplied when the callback was registered
* @param dlv The delivery being updated
* @param disp The new disposition for the delivery
* @param settled True iff the delivery is being settled
*/
typedef void (*qdr_delivery_update_t) (void *context, qdr_delivery_t *dlv, uint64_t disp, bool settled);
/**
* qdr_connection_close_t callback
*
* The core invokes this function when a connection to a remote container is to be closed.
*
* @param context The context supplied when the callback was registered
* @param conn The connection being closed
* @param error If the close is a result of an error, this is the error record to be used, else it's null
*/
typedef void (*qdr_connection_close_t) (void *context, qdr_connection_t *conn, qdr_error_t *error);
/**
* qdr_connection_trace_t callback
*
* This callback is invoked when per-connection tracing is being turned on of off. The new tracing
* state must be propagated down into the tracing capabilities of the lower layers of connection processing.
*
* @param context The context supplied when the callback was registered
* @param conn The connection being affected
* @param trace True to enable tracing for this connection, False to disable tracing for this connection
*/
typedef void (*qdr_connection_trace_t) (void *context, qdr_connection_t *conn, bool trace);
/**
******************************************************************************
* Protocol adaptor plugin functions
******************************************************************************
*/
/**
* qdr_protocol_adaptor
*
* Register a new protocol adaptor with the router core.
*
* @param core Pointer to the core object
* @param name The name of this adaptor's protocol
* @param context The context to be used in all of the callbacks
* @param callbacks Pointers to all of the callback functions used in the adaptor
* @return Pointer to a protocol adaptor object
*/
qdr_protocol_adaptor_t *qdr_protocol_adaptor(qdr_core_t *core,
const char *name,
void *context,
qdr_connection_activate_t activate,
qdr_link_first_attach_t first_attach,
qdr_link_second_attach_t second_attach,
qdr_link_detach_t detach,
qdr_link_flow_t flow,
qdr_link_offer_t offer,
qdr_link_drained_t drained,
qdr_link_drain_t drain,
qdr_link_push_t push,
qdr_link_deliver_t deliver,
qdr_link_get_credit_t get_credit,
qdr_delivery_update_t delivery_update,
qdr_connection_close_t conn_close,
qdr_connection_trace_t conn_trace);
/**
* qdr_protocol_adaptor_free
*
* Free the resources used for a protocol adaptor. This should be called during adaptor
* finalization.
*
* @param core Pointer to the core object
* @param adaptor Pointer to a protocol adaptor object returned by qdr_protocol_adaptor
*/
void qdr_protocol_adaptor_free(qdr_core_t *core, qdr_protocol_adaptor_t *adaptor);
/**
******************************************************************************
* Connection functions
******************************************************************************
*/
typedef enum {
QD_CONN_OPER_UP,
QD_CONN_OPER_DOWN,
} qd_conn_oper_status_t;
typedef enum {
QD_CONN_ADMIN_ENABLED,
QD_CONN_ADMIN_DELETED,
} qd_conn_admin_status_t;
typedef enum {
QD_LINK_ENDPOINT, ///< A link to a connected endpoint
QD_LINK_CONTROL, ///< A link to a peer router for control messages
QD_LINK_ROUTER, ///< A link to a peer router for routed messages
QD_LINK_EDGE_DOWNLINK, ///< Default link from an interior router to an edge router
QD_LINK_INTER_EDGE, ///< A link on an INTER_EDGE connection
} qd_link_type_t;
typedef enum {
QDR_ROLE_NORMAL,
QDR_ROLE_INTER_ROUTER,
QDR_ROLE_ROUTE_CONTAINER,
QDR_ROLE_EDGE_CONNECTION,
QDR_ROLE_INTER_ROUTER_DATA,
QDR_ROLE_INTER_EDGE,
} qdr_connection_role_t;
typedef void (*qdr_connection_bind_context_t) (qdr_connection_t *context, void *token);
/**
* qdr_connection_opened
*
* This function must be called once for every connection that is opened in the router.
* Once a new connection has been both remotely and locally opened, the core must be notified.
*
* @param core Pointer to the core object
* @param protocol_adaptor Pointer to the protocol adaptor handling the connection
* @param incoming True iff this connection is associated with a listener, False if a connector
* @param role The configured role of this connection
* @param cost If the role is inter_router, this is the configured cost for the connection.
* @param management_id - A unique identifier that is used in management and logging operations.
* @param label Optional label provided in the connection's configuration.
* @param strip_annotations_in True if configured to remove annotations on inbound messages.
* @param strip_annotations_out True if configured to remove annotations on outbound messages.
* @param link_capacity The capacity, in deliveries, for links in this connection.
* @return Pointer to a connection object that can be used to refer to this connection over its lifetime.
*/
qdr_connection_t *qdr_connection_opened(qdr_core_t *core,
qdr_protocol_adaptor_t *protocol_adaptor,
bool incoming,
qdr_connection_role_t role,
int cost,
uint64_t management_id,
const char *label,
const char *remote_container_id,
bool strip_annotations_in,
bool strip_annotations_out,
int link_capacity,
const qd_policy_spec_t *policy_spec,
qdr_connection_info_t *connection_info,
qdr_connection_bind_context_t context_binder,
void *bind_token);
/**
* qdr_connection_closed
*
* This function must be called when a connection is closed, either cleanly by protocol
* or uncleanly by lost connectivity. Once this function is called, the caller must never
* again refer to or use the connection pointer.
*
* @param conn The pointer returned by qdr_connection_opened
*/
void qdr_connection_closed(qdr_connection_t *conn);
/**
* qdr_connection_set_tracing
*
* Call the function if you want to turn proton trace logging on or off.
* Warning: Turning on proton trace logging will call each amqp frame to be logged and could
* overwhelm your log.
*
* @param qdr_connection_t *conn - the connection whose tracing needs to be turned on or off
* @param enable_tracing - true if proton trace logging needs to be turned on, false if proton logging needs to be turned off.
*/
void qdr_connection_set_tracing(qdr_connection_t *conn, bool enable_tracing);
/**
* qdr_core_close_connection
*
* This function is called when a connection is closed, usually by a management request.
* Initiates a core thread action that quite simply sets the closed flag on the passed in connection object
* and activates the connection. The qdr_connection_process() further processes this connection and calls
* back the appropriate protocol adaptor's conn_close_handler, where the io thread can further perform
* any appropriate cleanup.
*
* @param qdr_connection_t *conn - the connection that needs to be closed. The pointer returned by qdr_connection_opened
*/
void qdr_core_close_connection(qdr_connection_t *conn);
bool qdr_connection_route_container(qdr_connection_t *conn);
/**
* qdr_connection_set_context
*
* Store an arbitrary void pointer in the connection object.
*/
void qdr_connection_set_context(qdr_connection_t *conn, void *context);
/**
* qdr_connection_get_context
*
* Retrieve the stored void pointer from the connection object.
*/
void *qdr_connection_get_context(const qdr_connection_t *conn);
/**
* qdr_connection_role
*
* Retrieve the role of the connection object.
*/
qdr_connection_role_t qdr_connection_role(const qdr_connection_t *conn);
/**
* qdr_connection_get_tenant_space
*
* Retrieve the multi-tenant space for a connection. Returns 0 if there is
* no multi-tenancy on this connection.
*/
const char *qdr_connection_get_tenant_space(const qdr_connection_t *conn, int *len);
/**
* qdr_connection_process
*
* Allow the core to process work associated with this connection.
* This function MUST be called on a thread that exclusively owns
* this connection.
*
* @param conn The pointer returned by qdr_connection_opened
* @return The number of actions processed.
*/
int qdr_connection_process(qdr_connection_t *conn);
/**
******************************************************************************
* Terminus functions
******************************************************************************
*/
typedef struct pn_terminus_t pn_terminus_t;
/**
* qdr_terminus
*
* Create a qdr_terminus_t that contains all the content of the
* pn_terminus_t. Note that the pointer to the pn_terminus_t
* _will not_ be held or referenced further after this function
* returns.
*
* @param pn Pointer to a proton terminus object that will be copied into
* the qdr_terminus object
* @return Pointer to a newly allocated qdr_terminus object
*/
qdr_terminus_t *qdr_terminus(pn_terminus_t *pn);
/**
* qdr_terminus_free
*
* Free a qdr_terminus object once it is no longer needed.
*
* @param terminus The pointer returned by qdr_terminus()
*/
void qdr_terminus_free(qdr_terminus_t *terminus);
/**
* qdr_terminus_format
*
* Write a human-readable representation of the terminus content to the string
* in 'output'.
*
* @param terminus The pointer returned by qdr_terminus()
* @param output The string buffer where the result shall be written
* @param size Input: the number of bytes available in output for writing. Output: the
* number of bytes remaining after the operation.
*/
void qdr_terminus_format(qdr_terminus_t *terminus, char *output, size_t *size);
/**
* qdr_terminus_copy
*
* Copy the contents of the qdr_terminus into a proton terminus
*
* @param from A qdr_terminus pointer returned by qdr_terminus()
* @param to A proton terminus to be overwritten with the contents
* of 'from'
*/
void qdr_terminus_copy(qdr_terminus_t *from, pn_terminus_t *to);
/**
* qdr_terminus_add_capability
*
* Add a capability symbol to the terminus.
*
* @param term A qdr_terminus pointer returned by qdr_terminus()
* @param capability A string to be added as a symbol to the capability list
*/
void qdr_terminus_add_capability(qdr_terminus_t *term, const char *capability);
/**
* qdr_terminus_has_capability
*
* Check to see if a terminus has a particular capability.
*
* @param term A qdr_terminus pointer returned by qdr_terminus()
* @param capability A string describing a capability to be checked
* @return true iff the capability is advertised for this terminus
*/
bool qdr_terminus_has_capability(qdr_terminus_t *term, const char *capability);
/**
* qdr_terminus_is_anonymous
*
* Indicate whether this terminus represents an anonymous endpoint.
*
* @param term A qdr_terminus pointer returned by qdr_terminus()
* @return true iff the terminus is anonymous
*/
bool qdr_terminus_is_anonymous(qdr_terminus_t *term);
/**
* qdr_terminus_set_dynamic
*
* Set this terminus to be dynamic.
*
* @param term A qdr_terminus pointer returned by qdr_terminus()
*/
void qdr_terminus_set_dynamic(qdr_terminus_t *term);
/**
* qdr_terminus_is_dynamic
*
* Indicate whether this terminus represents a dynamic endpoint.
*
* @param term A qdr_terminus pointer returned by qdr_terminus()
* @return true iff the terminus is dynamic
*/
bool qdr_terminus_is_dynamic(qdr_terminus_t *term);
/**
* qdr_terminus_survives_disconnect
*
* Indicate whether this terminus will survive disconnection (i.e. if
* state is expected to be kept).
*
* @param term A qdr_terminus pointer returned by qdr_terminus()
* @return true iff the terminus has a timeout greater than 0 or an
* expiry-policy of never
*/
bool qdr_terminus_survives_disconnect(qdr_terminus_t *term);
/**
* qdr_terminus_set_address
*
* Set the terminus address
*
* @param term A qdr_terminus pointer returned by qdr_terminus()
* @param addr An AMQP address (null-terminated string)
*/
void qdr_terminus_set_address(qdr_terminus_t *term, const char *addr);
void qdr_terminus_set_address_iterator(qdr_terminus_t *term, qd_iterator_t *addr);
/**
* qdr_terminus_get_address
*
* Return the address of the terminus in the form of an iterator.
* The iterator is borrowed, the caller must not free the iterator.
*
* @param term A qdr_terminus pointer returned by qdr_terminus()
* @return A pointer to an iterator or 0 if the terminus is anonymous.
*/
qd_iterator_t *qdr_terminus_get_address(qdr_terminus_t *term);
/**
* qdr_terminus_insert_address_prefix
*
* Insert the given prefix into the terminus address
*
* @param term A qdr_terminus pointer returned by qdr_terminus()
* @param prefix null-terminated string
*/
void qdr_terminus_insert_address_prefix(qdr_terminus_t *term, const char *prefix);
/**
* qdr_terminus_strip_address_prefix
*
* Remove the given prefix from the terminus address
*
* @param term A qdr_terminus pointer returned by qdr_terminus()
* @param prefix null-terminated string
*/
void qdr_terminus_strip_address_prefix(qdr_terminus_t *term, const char *prefix);
/**
* qdr_terminus_dnp_address
*
* Return the address field in the dynamic-node-properties if it is there.
* This iterator is given, the caller must free it when it is no longer needed.
*
* @param term A qdr_terminus pointer returned by qdr_terminus()
* @return A pointer to an iterator or 0 if there is no such field.
*/
qd_iterator_t *qdr_terminus_dnp_address(qdr_terminus_t *term);
/**
* qdr_terminus_set_dnp_address_iterator
*
* Overwrite the dynamic-node-properties.address in the terminus
*
* @param term A qdr_terminus pointer returned by qdr_terminus()
* @param iter An iterator whose view shall be placed in the dnp.address
*/
void qdr_terminus_set_dnp_address_iterator(qdr_terminus_t *term, qd_iterator_t *iter);
/**
******************************************************************************
* Link functions
******************************************************************************
*/
/**
* qdr_link_set_context
*
* Store an arbitrary void pointer in the link object.
*/
void qdr_link_set_context(qdr_link_t *link, void *context);
/**
* qdr_link_get_context
*
* Retrieve the stored void pointer from the link object.
*/
void *qdr_link_get_context(const qdr_link_t *link);
/**
* qdr_link_type
*
* Retrieve the link-type from the link object.
*
* @param link Link object
* @return Link-type
*/
qd_link_type_t qdr_link_type(const qdr_link_t *link);
/**
* qdr_link_direction
*
* Retrieve the link-direction from the link object.
*
* @param link Link object
* @return Link-direction
*/
qd_direction_t qdr_link_direction(const qdr_link_t *link);
/**
* qdr_link_internal_address
*
* If this link is associated with an auto_link and the auto_link has different
* internal and external addresses, return the internal (routing) address.
*
* @param link Link object
* @return 0 or the auto_link's internal address.
*/
const char *qdr_link_internal_address(const qdr_link_t *link);
/**
* qdr_link_is_anonymous
*
* Indicate whether the link is anonymous. Note that this is determined inside
* the core thread. In the time between first creating the link and when the
* core thread determines its status, a link will indicate "true" for being anonymous.
* The reason for this is to be conservative. The anonymous check is an optimization
* used by the caller to skip parsing the "to" field for messages on non-anonymous links.
*
* @param link Link object
* @return True if the link is anonymous or the link hasn't been processed yet.
*/
bool qdr_link_is_anonymous(const qdr_link_t *link);
/**
* qdr_link_is_core_endpoint
*
* Indicate whether the link is terminated in the router core. These links are used by the core to send and receive
* messages.
*
* @param link Link object
* @return True if the link is terminated in the core
*/
bool qdr_link_is_core_endpoint(const qdr_link_t *link);
/**
* qdr_link_strip_annotations_in
*
* Indicate whether the link's connection is configured to strip message annotations on inbound messages.
*/
bool qdr_link_strip_annotations_in(const qdr_link_t *link);
/**
* qdr_link_strip_annotations_out
*
* Indicate whether the link's connection is configured to strip message annotations on outbound messages.
*/
bool qdr_link_strip_annotations_out(const qdr_link_t *link);
/**
* qdr_link_stalled_outbound
*
* Tell the link that it has been stalled outbound due to back-pressure from the
* transport buffers. Stalling is undone during link-flow processing.
*/
void qdr_link_stalled_outbound(qdr_link_t *link);
/**
* qdr_link_set_user_streaming
*
* Allow this link to carry streaming messages without getting involved with the connection's
* streaming-link pool. This allows protocol adaptors to "manually" create streaming links.
* This function will typically be invoked right after qdr_link_first_attach.
*/
void qdr_link_set_user_streaming(qdr_link_t *link);
/**
* qdr_link_name
*
* Retrieve the name of the link.
*
* @param link Link object
* @return The link's name
*/
const char *qdr_link_name(const qdr_link_t *link);
/**
* qdr_link_first_attach
*
* This function is invoked when a first-attach (not a response to an earlier attach)
* arrives for a connection.
*
* @param conn Connection pointer returned by qdr_connection_opened
* @param dir Direction of the new link, incoming or outgoing
* @param source Source terminus of the attach
* @param target Target terminus of the attach
* @param name - name of the link
* @param terminus_addr - terminus address if any
* @param no_route If true, new deliveries are not to be routed to this link
* @param initial_delivery (optional) Move this delivery from its existing link to the head of this link's buffer
* @param link_id - set to the management id of the new link
* @return A pointer to a new qdr_link_t object to track the link
*/
qdr_link_t *qdr_link_first_attach(qdr_connection_t *conn,
qd_direction_t dir,
qdr_terminus_t *source,
qdr_terminus_t *target,
const char *name,
const char *terminus_addr,
bool no_route,
qdr_delivery_t *initial_delivery,
uint64_t *link_id);
/**
* qdr_link_second_attach
*
* This function is invoked when a second-attach (a response to an attach we sent)
* arrives for a connection.
*
* @param link The link pointer returned by qdr_link_first_attach or in a FIRST_ATTACH event.
* @param source Source terminus of the attach
* @param target Target terminus of the attach
*/
void qdr_link_second_attach(qdr_link_t *link, qdr_terminus_t *source, qdr_terminus_t *target);
/**
* qdr_link_detach_received
*
* This function is invoked when a link detach performative arrives from the remote peer. This may the first detach
* (peer-initiated link detach) or in response to a detach sent by the router (second detach).
*
* @param link The link pointer returned by qdr_link_first_attach or in a FIRST_ATTACH event.
* @param error The link error from the detach frame or 0 if none.
*/
void qdr_link_detach_received(qdr_link_t *link, qdr_error_t *error);
/**
* qdr_link_closed
*
* This function is invoked by the adaptor when the link has fully closed. This will be the last call made by the
* adaptor for this link. This may be called as a result of a successful detach handshake or due to link loss. This will
* also be called during adaptor shutdown on any outstanding links.
*
* The core may free the qdr_link_t by this call. The adaptor MUST NOT reference the qdr_link_t on return from this
* call.
*
* @param link The link pointer returned by qdr_link_first_attach or in a FIRST_ATTACH event.
* @param forced True if the link was closed due to failure or shutdown. False if closed by clean detach handshake.
*/
void qdr_link_closed(qdr_link_t *link, bool forced);
/**
* qdr_link_deliver
*
* Deliver a message to the router core for forwarding. This function is used in cases where
* the link contains all the information needed for proper message routing (i.e. non-anonymous
* inbound links).
*
* @param link Pointer to the link over which the message arrived.
* @param msg Pointer to the delivered message. The sender is giving this reference to the router
* core. The sender _must not_ free or otherwise use the message after invoking this function.
* @param ingress Field iterator referencing the value of the ingress-router header. NOTE: This
* iterator is assumed to reference content in the message that will stay valid
* through the lifetime of the message.
* @param settled True iff the delivery is pre-settled.
* @param link_exclusion If present, this is a bitmask of inter-router links that should not be used
* to send this message. This bitmask is created by the trace_mask module and
* it built on the trace header from a received message.
* @param ingress_index The bitmask index of the router that this delivery entered the network through.
* @param remote_disposition as set by sender on the transfer
* @param remote_disposition_state as set by sender on the transfer
* @return Pointer to the qdr_delivery that will track the lifecycle of this delivery on this link.
*/
qdr_delivery_t *qdr_link_deliver(qdr_link_t *link, qd_message_t *msg, qd_iterator_t *ingress,
bool settled, qd_bitmask_t *link_exclusion, int ingress_index,
uint64_t remote_disposition,
qd_delivery_state_t *remote_state);
qdr_delivery_t *qdr_link_deliver_to(qdr_link_t *link, qd_message_t *msg,
qd_iterator_t *ingress, qd_iterator_t *addr,
bool settled, qd_bitmask_t *link_exclusion, int ingress_index,
uint64_t remote_disposition,
qd_delivery_state_t *remote_state);
qdr_delivery_t *qdr_link_deliver_to_core(qdr_link_t *link, qd_message_t *msg, bool settled,
uint64_t remote_disposition,
qd_delivery_state_t *remote_state);
/**
* qdr_link_process_deliveries
*
* This function is called by the protocol adaptor in the context of the link_push
* callback. It provides the core module access to the IO thread so the core can
* deliver outgoing messages to the adaptor.
*
* @param core Pointer to the router core object
* @param link Pointer to the link being processed
* @param credit The maximum number of deliveries to be processed on this link
* @return The number of deliveries that were completed during the processing
*/
int qdr_link_process_deliveries(qdr_core_t *core, qdr_link_t *link, int credit);
/**
* qdr_link_complete_sent_message
*
* If an outgoing message is completed outside of the context of the link_deliver callback,
* this function must be called to inform the router core that the delivery on the head of
* the link's undelivered list can be moved out of that list. Ensure that the send-complete
* status of the message has been set before calling this function. This function will check
* the send-complete status of the head delivery on the link's undelivered list. If it is
* true, that delivery will be removed from the undelivered list.
*
* DO NOT call this function from within the link_deliver callback. Use it only if you must
* asynchronously complete the sending of the current message.
*
* This will typically occur when a message delivered to the protocol adaptor cannot be sent
* on the wire due to back-pressure. In this case, the removal of the back pressure is the
* stimulus for completing the send of the message.
*
* @param core Pointer to the router core object
* @param link Pointer to the link on which the head delivery has been completed
*/
void qdr_link_complete_sent_message(qdr_core_t *core, qdr_link_t *link);
void qdr_link_flow(qdr_core_t *core, qdr_link_t *link, int credit, bool drain_mode);
/**
* Sets the link's drain flag to false and sets credit to core to zero.
* The passed in link has been drained and hence no longer in drain mode.
* Call this right after calling pn_link_drained
*
* @param core - router core
* @param link - the link that has been drained
*/
void qdr_link_set_drained(qdr_core_t *core, qdr_link_t *link);
/**
* Extract the disposition and delivery state data that is to be sent to the
* remote endpoint via the delivery. Caller takes ownership of the returned
* delivery_state and must free it when done.
*/
qd_delivery_state_t *qdr_delivery_take_local_delivery_state(qdr_delivery_t *dlv, uint64_t *dispo);
qdr_connection_info_t *qdr_connection_info(bool is_encrypted,
bool is_authenticated,
bool opened,
char *sasl_mechanisms,
qd_direction_t dir,
const char *host,
const char *ssl_proto,
const char *ssl_cipher,
const char *user,
const char *container,
pn_data_t *connection_properties,
int ssl_ssf,
bool ssl,
const char *version,
bool streaming_links,
bool connection_trunking);
void qdr_connection_info_set_group_correlator(qdr_connection_info_t *info, const char *correlator);
void qdr_connection_info_set_tls(qdr_connection_info_t *info, bool enabled, char *version, char *ciphers, int ssf);
void qd_adaptor_listener_init(void);
void qd_adaptor_listener_finalize(void);
/**
******************************************************************************
* Listener State
******************************************************************************
*/
typedef enum {
QD_LISTENER_OPER_DOWN,
QD_LISTENER_OPER_OPENING, // waiting for proactor PN_LISTENER_OPEN event
QD_LISTENER_OPER_UP,
} qd_listener_oper_status_t;
typedef enum {
QD_LISTENER_ADMIN_ENABLED,
QD_LISTENER_ADMIN_DELETED
} qd_listener_admin_status_t;
#endif