1 // SPDX-License-Identifier: LGPL-2.1-or-later
3 * This file is part of the PCEPlib, a PCEP protocol library.
5 * Copyright (C) 2020 Volta Networks https://voltanet.io/
7 * Author : Brady Johnson <brady@voltanet.io>
13 * Declaration of public API functions.
16 #ifndef INCLUDE_PCEPSOCKETCOMM_H_
17 #define INCLUDE_PCEPSOCKETCOMM_H_
20 #include <arpa/inet.h> // sockaddr_in
21 #include <netinet/tcp.h>
24 #include "pcep_utils_queue.h"
26 #define MAX_RECVD_MSG_SIZE 2048
29 * A socket_comm_session can be initialized with 1 of 2 types of mutually
30 * exclusive message callbacks:
31 * - message_received_handler : the socket_comm library reads the message and
32 * calls the callback with the message_data and message_length. this callback
33 * should be used for smaller/simpler messages.
34 * - message_ready_to_read_handler : the socket_comm library will call this
35 * callback when a message is ready to be read on a socket_fd. this callback
36 * should be used if the
39 /* message received handler that receives the message data and message length */
40 typedef void (*message_received_handler
)(void *session_data
,
41 const char *message_data
,
42 unsigned int message_length
);
43 /* message ready received handler that should read the message on socket_fd
44 * and return the number of bytes read */
45 typedef int (*message_ready_to_read_handler
)(void *session_data
, int socket_fd
);
46 /* callback handler called when a messages is sent */
47 typedef void (*message_sent_notifier
)(void *session_data
, int socket_fd
);
48 /* callback handler called when the socket is closed */
49 typedef void (*connection_except_notifier
)(void *session_data
, int socket_fd
);
51 /* Function pointers when an external socket infrastructure is used */
52 typedef int (*ext_socket_write
)(void *infra_data
, void **infra_socket_data
,
54 typedef int (*ext_socket_read
)(void *infra_data
, void **infra_socket_data
,
56 typedef int (*ext_socket_pthread_create_callback
)(
57 pthread_t
*pthread_id
, const pthread_attr_t
*attr
,
58 void *(*start_routine
)(void *), void *data
, const char *thread_name
);
60 typedef struct pcep_socket_comm_session_
{
61 message_received_handler message_handler
;
62 message_ready_to_read_handler message_ready_to_read_handler
;
63 message_sent_notifier message_sent_handler
;
64 connection_except_notifier conn_except_notifier
;
66 struct sockaddr_in src_sock_addr_ipv4
;
67 struct sockaddr_in6 src_sock_addr_ipv6
;
69 union dest_sock_addr
{
70 struct sockaddr_in dest_sock_addr_ipv4
;
71 struct sockaddr_in6 dest_sock_addr_ipv6
;
74 uint32_t connect_timeout_millis
;
77 queue_handle
*message_queue
;
78 char received_message
[MAX_RECVD_MSG_SIZE
];
80 bool close_after_write
;
81 void *external_socket_data
; /* used for external socket infra */
82 /* should be used with is_tcp_auth_md5 flag */
83 char tcp_authentication_str
[PCEP_MD5SIG_MAXKEYLEN
+ 1];
85 bool is_tcp_auth_md5
; /* flag to distinguish between rfc 2385 (md5) and
88 } pcep_socket_comm_session
;
91 /* Need to document that when the msg_rcv_handler is called, the data needs
92 * to be handled in the same function call, else it may be overwritten by
93 * the next read from this socket */
96 /* Initialize the Socket Comm infrastructure, with either an internal pthread
97 * or with an external infrastructure.
98 * If an internal pthread infrastructure is to be used, then it is not necessary
99 * to explicitly call initialize_socket_comm_loop() as it will be called
100 * internally when a socket comm session is initialized. */
102 /* Initialize the Socket Comm infrastructure with an internal pthread */
103 bool initialize_socket_comm_loop(void);
104 /* Initialize the Socket Comm infrastructure with an external infrastructure.
105 * Notice: If the thread_create_func is set, then both the socket_read_cb
106 * and the socket_write_cb SHOULD be NULL. */
107 bool initialize_socket_comm_external_infra(
108 void *external_infra_data
, ext_socket_read socket_read_cb
,
109 ext_socket_write socket_write_cb
,
110 ext_socket_pthread_create_callback thread_create_func
);
112 /* The msg_rcv_handler and msg_ready_handler are mutually exclusive, and only
113 * one can be set (as explained above), else NULL will be returned. */
114 pcep_socket_comm_session
*
115 socket_comm_session_initialize(message_received_handler msg_rcv_handler
,
116 message_ready_to_read_handler msg_ready_handler
,
117 message_sent_notifier msg_sent_notifier
,
118 connection_except_notifier notifier
,
119 struct in_addr
*dst_ip
, short dst_port
,
120 uint32_t connect_timeout_millis
,
121 const char *tcp_authentication_str
,
122 bool is_tcp_auth_md5
, void *session_data
);
124 pcep_socket_comm_session
*socket_comm_session_initialize_ipv6(
125 message_received_handler msg_rcv_handler
,
126 message_ready_to_read_handler msg_ready_handler
,
127 message_sent_notifier msg_sent_notifier
,
128 connection_except_notifier notifier
, struct in6_addr
*dst_ip
,
129 short dst_port
, uint32_t connect_timeout_millis
,
130 const char *tcp_authentication_str
, bool is_tcp_auth_md5
,
133 pcep_socket_comm_session
*socket_comm_session_initialize_with_src(
134 message_received_handler msg_rcv_handler
,
135 message_ready_to_read_handler msg_ready_handler
,
136 message_sent_notifier msg_sent_notifier
,
137 connection_except_notifier notifier
, struct in_addr
*src_ip
,
138 short src_port
, struct in_addr
*dst_ip
, short dst_port
,
139 uint32_t connect_timeout_millis
, const char *tcp_authentication_str
,
140 bool is_tcp_auth_md5
, void *session_data
);
142 pcep_socket_comm_session
*socket_comm_session_initialize_with_src_ipv6(
143 message_received_handler msg_rcv_handler
,
144 message_ready_to_read_handler msg_ready_handler
,
145 message_sent_notifier msg_sent_notifier
,
146 connection_except_notifier notifier
, struct in6_addr
*src_ip
,
147 short src_port
, struct in6_addr
*dst_ip
, short dst_port
,
148 uint32_t connect_timeout_millis
, const char *tcp_authentication_str
,
149 bool is_tcp_auth_md5
, void *session_data
);
151 bool socket_comm_session_teardown(
152 pcep_socket_comm_session
*socket_comm_session
);
154 bool socket_comm_session_connect_tcp(
155 pcep_socket_comm_session
*socket_comm_session
);
157 /* Immediately close the TCP connection, irregardless if there are pending
158 * messages to be sent. */
159 bool socket_comm_session_close_tcp(
160 pcep_socket_comm_session
*socket_comm_session
);
162 /* Sets a flag to close the TCP connection either after all the pending messages
163 * are written, or if there are no pending messages, the next time the socket is
164 * checked to be writeable. */
165 bool socket_comm_session_close_tcp_after_write(
166 pcep_socket_comm_session
*socket_comm_session
);
168 void socket_comm_session_send_message(
169 pcep_socket_comm_session
*socket_comm_session
,
170 const char *encoded_message
, unsigned int msg_length
,
171 bool free_after_send
);
173 /* If an external Socket infra like FRR is used, then these functions will
174 * be called when a socket is ready to read/write in the external infra.
175 * Implemented in pcep_socket_comm_loop.c */
176 int pceplib_external_socket_read(int fd
, void *payload
);
177 int pceplib_external_socket_write(int fd
, void *payload
);
179 /* the socket comm loop is started internally by
180 * socket_comm_session_initialize()
181 * but needs to be explicitly stopped with this call. */
182 bool destroy_socket_comm_loop(void);
184 int socket_fd_node_compare(void *list_entry
, void *new_entry
);
186 #endif /* INCLUDE_PCEPSOCKETCOMM_H_ */