]>
Commit | Line | Data |
---|---|---|
74971473 JG |
1 | /* |
2 | * This file is part of the PCEPlib, a PCEP protocol library. | |
3 | * | |
4 | * Copyright (C) 2020 Volta Networks https://voltanet.io/ | |
5 | * | |
6 | * This library is free software; you can redistribute it and/or | |
7 | * modify it under the terms of the GNU Lesser General Public | |
8 | * License as published by the Free Software Foundation; either | |
9 | * version 2 of the License, or (at your option) any later version. | |
10 | * | |
11 | * This library is distributed in the hope that it will be useful, | |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 | * Lesser General Public License for more details. | |
15 | * | |
16 | * You should have received a copy of the GNU General Public License | |
17 | * along with this program. If not, see <https://www.gnu.org/licenses/>. | |
18 | * | |
19 | * Author : Brady Johnson <brady@voltanet.io> | |
20 | * | |
21 | */ | |
22 | ||
23 | ||
24 | /* | |
25 | * Declaration of public API functions. | |
26 | */ | |
27 | ||
28 | #ifndef INCLUDE_PCEPSOCKETCOMM_H_ | |
29 | #define INCLUDE_PCEPSOCKETCOMM_H_ | |
30 | ||
31 | #include "pcep.h" | |
32 | #include <arpa/inet.h> // sockaddr_in | |
33 | #include <netinet/tcp.h> | |
34 | #include <stdbool.h> | |
35 | ||
36 | #include "pcep_utils_queue.h" | |
37 | ||
38 | #define MAX_RECVD_MSG_SIZE 2048 | |
39 | ||
40 | /* | |
41 | * A socket_comm_session can be initialized with 1 of 2 types of mutually | |
42 | * exclusive message callbacks: | |
43 | * - message_received_handler : the socket_comm library reads the message and | |
44 | * calls the callback with the message_data and message_length. this callback | |
45 | * should be used for smaller/simpler messages. | |
46 | * - message_ready_to_read_handler : the socket_comm library will call this | |
47 | * callback when a message is ready to be read on a socket_fd. this callback | |
48 | * should be used if the | |
49 | */ | |
50 | ||
51 | /* message received handler that receives the message data and message length */ | |
52 | typedef void (*message_received_handler)(void *session_data, | |
53 | const char *message_data, | |
54 | unsigned int message_length); | |
55 | /* message ready received handler that should read the message on socket_fd | |
56 | * and return the number of bytes read */ | |
57 | typedef int (*message_ready_to_read_handler)(void *session_data, int socket_fd); | |
58 | /* callback handler called when a messages is sent */ | |
59 | typedef void (*message_sent_notifier)(void *session_data, int socket_fd); | |
60 | /* callback handler called when the socket is closed */ | |
61 | typedef void (*connection_except_notifier)(void *session_data, int socket_fd); | |
62 | ||
63 | /* Function pointers when an external socket infrastructure is used */ | |
64 | typedef int (*ext_socket_write)(void *infra_data, void **infra_socket_data, | |
65 | int fd, void *data); | |
66 | typedef int (*ext_socket_read)(void *infra_data, void **infra_socket_data, | |
67 | int fd, void *data); | |
68 | typedef int (*ext_socket_pthread_create_callback)( | |
69 | pthread_t *pthread_id, const pthread_attr_t *attr, | |
70 | void *(*start_routine)(void *), void *data, const char *thread_name); | |
71 | ||
72 | typedef struct pcep_socket_comm_session_ { | |
73 | message_received_handler message_handler; | |
74 | message_ready_to_read_handler message_ready_to_read_handler; | |
75 | message_sent_notifier message_sent_handler; | |
76 | connection_except_notifier conn_except_notifier; | |
77 | union src_sock_addr { | |
78 | struct sockaddr_in src_sock_addr_ipv4; | |
79 | struct sockaddr_in6 src_sock_addr_ipv6; | |
80 | } src_sock_addr; | |
81 | union dest_sock_addr { | |
82 | struct sockaddr_in dest_sock_addr_ipv4; | |
83 | struct sockaddr_in6 dest_sock_addr_ipv6; | |
84 | } dest_sock_addr; | |
85 | bool is_ipv6; | |
86 | uint32_t connect_timeout_millis; | |
87 | int socket_fd; | |
88 | void *session_data; | |
89 | queue_handle *message_queue; | |
90 | char received_message[MAX_RECVD_MSG_SIZE]; | |
91 | int received_bytes; | |
92 | bool close_after_write; | |
93 | void *external_socket_data; /* used for external socket infra */ | |
94 | char tcp_authentication_str[TCP_MD5SIG_MAXKEYLEN | |
95 | + 1]; /* should be used with is_tcp_auth_md5 | |
96 | flag */ | |
97 | bool is_tcp_auth_md5; /* flag to distinguish between rfc 2385 (md5) and | |
98 | rfc 5925 (tcp-ao) */ | |
99 | ||
100 | } pcep_socket_comm_session; | |
101 | ||
102 | ||
103 | /* Need to document that when the msg_rcv_handler is called, the data needs | |
104 | * to be handled in the same function call, else it may be overwritten by | |
105 | * the next read from this socket */ | |
106 | ||
107 | ||
108 | /* Initialize the Socket Comm infrastructure, with either an internal pthread | |
109 | * or with an external infrastructure. | |
110 | * If an internal pthread infrastructure is to be used, then it is not necessary | |
111 | * to explicitly call initialize_socket_comm_loop() as it will be called | |
112 | * internally when a socket comm session is initialized. */ | |
113 | ||
114 | /* Initialize the Socket Comm infrastructure with an internal pthread */ | |
115 | bool initialize_socket_comm_loop(void); | |
116 | /* Initialize the Socket Comm infrastructure with an external infrastructure. | |
117 | * Notice: If the thread_create_func is set, then both the socket_read_cb | |
118 | * and the socket_write_cb SHOULD be NULL. */ | |
119 | bool initialize_socket_comm_external_infra( | |
120 | void *external_infra_data, ext_socket_read socket_read_cb, | |
121 | ext_socket_write socket_write_cb, | |
122 | ext_socket_pthread_create_callback thread_create_func); | |
123 | ||
124 | /* The msg_rcv_handler and msg_ready_handler are mutually exclusive, and only | |
125 | * one can be set (as explained above), else NULL will be returned. */ | |
126 | pcep_socket_comm_session * | |
127 | socket_comm_session_initialize(message_received_handler msg_rcv_handler, | |
128 | message_ready_to_read_handler msg_ready_handler, | |
129 | message_sent_notifier msg_sent_notifier, | |
130 | connection_except_notifier notifier, | |
131 | struct in_addr *dst_ip, short dst_port, | |
132 | uint32_t connect_timeout_millis, | |
133 | const char *tcp_authentication_str, | |
134 | bool is_tcp_auth_md5, void *session_data); | |
135 | ||
136 | pcep_socket_comm_session *socket_comm_session_initialize_ipv6( | |
137 | message_received_handler msg_rcv_handler, | |
138 | message_ready_to_read_handler msg_ready_handler, | |
139 | message_sent_notifier msg_sent_notifier, | |
140 | connection_except_notifier notifier, struct in6_addr *dst_ip, | |
141 | short dst_port, uint32_t connect_timeout_millis, | |
142 | const char *tcp_authentication_str, bool is_tcp_auth_md5, | |
143 | void *session_data); | |
144 | ||
145 | pcep_socket_comm_session *socket_comm_session_initialize_with_src( | |
146 | message_received_handler msg_rcv_handler, | |
147 | message_ready_to_read_handler msg_ready_handler, | |
148 | message_sent_notifier msg_sent_notifier, | |
149 | connection_except_notifier notifier, struct in_addr *src_ip, | |
150 | short src_port, struct in_addr *dst_ip, short dst_port, | |
151 | uint32_t connect_timeout_millis, const char *tcp_authentication_str, | |
152 | bool is_tcp_auth_md5, void *session_data); | |
153 | ||
154 | pcep_socket_comm_session *socket_comm_session_initialize_with_src_ipv6( | |
155 | message_received_handler msg_rcv_handler, | |
156 | message_ready_to_read_handler msg_ready_handler, | |
157 | message_sent_notifier msg_sent_notifier, | |
158 | connection_except_notifier notifier, struct in6_addr *src_ip, | |
159 | short src_port, struct in6_addr *dst_ip, short dst_port, | |
160 | uint32_t connect_timeout_millis, const char *tcp_authentication_str, | |
161 | bool is_tcp_auth_md5, void *session_data); | |
162 | ||
163 | bool socket_comm_session_teardown( | |
164 | pcep_socket_comm_session *socket_comm_session); | |
165 | ||
166 | bool socket_comm_session_connect_tcp( | |
167 | pcep_socket_comm_session *socket_comm_session); | |
168 | ||
169 | /* Immediately close the TCP connection, irregardless if there are pending | |
170 | * messages to be sent. */ | |
171 | bool socket_comm_session_close_tcp( | |
172 | pcep_socket_comm_session *socket_comm_session); | |
173 | ||
174 | /* Sets a flag to close the TCP connection either after all the pending messages | |
175 | * are written, or if there are no pending messages, the next time the socket is | |
176 | * checked to be writeable. */ | |
177 | bool socket_comm_session_close_tcp_after_write( | |
178 | pcep_socket_comm_session *socket_comm_session); | |
179 | ||
180 | void socket_comm_session_send_message( | |
181 | pcep_socket_comm_session *socket_comm_session, | |
182 | const char *encoded_message, unsigned int msg_length, | |
183 | bool free_after_send); | |
184 | ||
185 | /* If an external Socket infra like FRR is used, then these functions will | |
186 | * be called when a socket is ready to read/write in the external infra. | |
187 | * Implemented in pcep_socket_comm_loop.c */ | |
188 | int pceplib_external_socket_read(int fd, void *payload); | |
189 | int pceplib_external_socket_write(int fd, void *payload); | |
190 | ||
191 | /* the socket comm loop is started internally by | |
192 | * socket_comm_session_initialize() | |
193 | * but needs to be explicitly stopped with this call. */ | |
194 | bool destroy_socket_comm_loop(void); | |
195 | ||
196 | int socket_fd_node_compare(void *list_entry, void *new_entry); | |
197 | ||
198 | #endif /* INCLUDE_PCEPSOCKETCOMM_H_ */ |