]>
Commit | Line | Data |
---|---|---|
acddc0ed | 1 | // SPDX-License-Identifier: LGPL-2.1-or-later |
74971473 JG |
2 | /* |
3 | * This file is part of the PCEPlib, a PCEP protocol library. | |
4 | * | |
5 | * Copyright (C) 2020 Volta Networks https://voltanet.io/ | |
6 | * | |
74971473 JG |
7 | * Author : Brady Johnson <brady@voltanet.io> |
8 | * | |
9 | */ | |
10 | ||
11 | ||
12 | /* | |
13 | * Declaration of public API functions. | |
14 | */ | |
15 | ||
16 | #ifndef INCLUDE_PCEPSOCKETCOMM_H_ | |
17 | #define INCLUDE_PCEPSOCKETCOMM_H_ | |
18 | ||
19 | #include "pcep.h" | |
20 | #include <arpa/inet.h> // sockaddr_in | |
21 | #include <netinet/tcp.h> | |
22 | #include <stdbool.h> | |
23 | ||
24 | #include "pcep_utils_queue.h" | |
25 | ||
26 | #define MAX_RECVD_MSG_SIZE 2048 | |
27 | ||
28 | /* | |
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 | |
37 | */ | |
38 | ||
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); | |
50 | ||
51 | /* Function pointers when an external socket infrastructure is used */ | |
52 | typedef int (*ext_socket_write)(void *infra_data, void **infra_socket_data, | |
53 | int fd, void *data); | |
54 | typedef int (*ext_socket_read)(void *infra_data, void **infra_socket_data, | |
55 | int fd, void *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); | |
59 | ||
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; | |
65 | union src_sock_addr { | |
66 | struct sockaddr_in src_sock_addr_ipv4; | |
67 | struct sockaddr_in6 src_sock_addr_ipv6; | |
68 | } src_sock_addr; | |
69 | union dest_sock_addr { | |
70 | struct sockaddr_in dest_sock_addr_ipv4; | |
71 | struct sockaddr_in6 dest_sock_addr_ipv6; | |
72 | } dest_sock_addr; | |
73 | bool is_ipv6; | |
74 | uint32_t connect_timeout_millis; | |
75 | int socket_fd; | |
76 | void *session_data; | |
77 | queue_handle *message_queue; | |
78 | char received_message[MAX_RECVD_MSG_SIZE]; | |
79 | int received_bytes; | |
80 | bool close_after_write; | |
81 | void *external_socket_data; /* used for external socket infra */ | |
2a034138 MS |
82 | /* should be used with is_tcp_auth_md5 flag */ |
83 | char tcp_authentication_str[PCEP_MD5SIG_MAXKEYLEN + 1]; | |
84 | ||
74971473 JG |
85 | bool is_tcp_auth_md5; /* flag to distinguish between rfc 2385 (md5) and |
86 | rfc 5925 (tcp-ao) */ | |
87 | ||
88 | } pcep_socket_comm_session; | |
89 | ||
90 | ||
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 */ | |
94 | ||
95 | ||
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. */ | |
101 | ||
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); | |
111 | ||
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); | |
123 | ||
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, | |
131 | void *session_data); | |
132 | ||
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); | |
141 | ||
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); | |
150 | ||
151 | bool socket_comm_session_teardown( | |
152 | pcep_socket_comm_session *socket_comm_session); | |
153 | ||
154 | bool socket_comm_session_connect_tcp( | |
155 | pcep_socket_comm_session *socket_comm_session); | |
156 | ||
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); | |
161 | ||
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); | |
167 | ||
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); | |
172 | ||
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); | |
178 | ||
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); | |
183 | ||
184 | int socket_fd_node_compare(void *list_entry, void *new_entry); | |
185 | ||
186 | #endif /* INCLUDE_PCEPSOCKETCOMM_H_ */ |