Add void (*on_connected)(endpoint_t *ep) field to endpoint_t with endpoint_set_on_connected() helper. io_handler fires it exactly once immediately after ssl_handshake_done=1 then nulls the pointer. Enables ha_start_election_async to send OP_requestVote as soon as the TLS handshake with a peer completes — no blocking SSL_connect. 6 new unit tests pass; controller suite 1/1 OK.
147 lines
4.7 KiB
C
147 lines
4.7 KiB
C
#if !defined(_NETIO_H_)
|
|
|
|
#define _NETIO_H_ 1
|
|
|
|
#include <openssl/err.h>
|
|
#include <openssl/ssl.h>
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <sys/epoll.h>
|
|
#include <sys/socket.h>
|
|
|
|
#include "dataq.h"
|
|
#include "mylock.h"
|
|
|
|
typedef int (*conn_handler_t)(struct epoll_event*);
|
|
typedef int (*msg_handler_t)(void*);
|
|
typedef int (*err_handler_t)(void*);
|
|
|
|
typedef struct {
|
|
char* name;
|
|
char* key;
|
|
} xce_peerinfo_t;
|
|
|
|
#define IO_MON_INPUT (0x01)
|
|
#define IO_MON_OUTPUT (0x02)
|
|
|
|
typedef struct {
|
|
data_item_t link;
|
|
uint64_t sz;
|
|
char* data;
|
|
} io_packet_t;
|
|
|
|
#define ITPTR_TO_PACKET(it) \
|
|
((io_packet_t*)(((char*)it) - offsetof(io_packet_t, link)))
|
|
|
|
typedef struct {
|
|
mylock_t lock;
|
|
int epoll_fd;
|
|
struct epoll_event ev;
|
|
pthread_t worker;
|
|
SSL_CTX* ssl_ctx;
|
|
} iomgr_t;
|
|
|
|
typedef enum {
|
|
FSM_IO_READ = 0,
|
|
FSM_IO_WRITE
|
|
} io_fsm_op_t;
|
|
|
|
typedef enum {
|
|
FSM_STATE_INIT = 0,
|
|
FSM_STATE_READ_PKT_HEAD,
|
|
FSM_STATE_READ_PKT,
|
|
FSM_STATE_WRITE_PKT_HEAD,
|
|
FSM_STATE_WRITE_PKT,
|
|
FSM_STATE_DONE,
|
|
FSM_STATE_ERROR
|
|
} io_fsm_state_t;
|
|
|
|
typedef struct {
|
|
void* ep;
|
|
io_fsm_op_t op;
|
|
io_fsm_state_t state;
|
|
io_packet_t* pkt;
|
|
size_t iocount;
|
|
} io_fsm_t;
|
|
|
|
typedef struct endpoint_t {
|
|
mylock_t lock;
|
|
iomgr_t* iomgr;
|
|
SSL* ssl;
|
|
int fd;
|
|
int idx;
|
|
int flags;
|
|
unsigned int busy : 1;
|
|
unsigned int ssl_handshake_done : 1;
|
|
dataq_t outq;
|
|
uint64_t seq;
|
|
conn_handler_t conn_handler;
|
|
void* owner;
|
|
void* data;
|
|
io_fsm_t fsm_in;
|
|
io_fsm_t fsm_out;
|
|
xce_peerinfo_t* peer;
|
|
msg_handler_t msg_handler;
|
|
err_handler_t err_handler;
|
|
time_t ts_last_in;
|
|
time_t ts_last_out;
|
|
void (*on_connected)(struct endpoint_t *ep); /* fire-once; called in iomgr thread after ssl_handshake_done=1 */
|
|
} endpoint_t;
|
|
|
|
#define INVOKE_MSG_HANDLER(ep) \
|
|
do { \
|
|
TRACE("%s msg handler %p", __func__, (ep)->msg_handler); \
|
|
if ((ep)->msg_handler != NULL) { \
|
|
(ep)->msg_handler(ep); \
|
|
/* passing ownership of packet to upper layer */ \
|
|
(ep)->fsm_in.pkt = NULL; \
|
|
} \
|
|
} while (0)
|
|
|
|
#define INVOKE_ERR_HANDLER(ep) \
|
|
do { \
|
|
if ((ep)->err_handler != NULL) { \
|
|
(ep)->err_handler(ep); \
|
|
} \
|
|
} while (0)
|
|
|
|
typedef struct {
|
|
endpoint_t* ep;
|
|
io_packet_t* pkt;
|
|
} io_task_data_t;
|
|
|
|
extern int alloc_packet(io_packet_t*);
|
|
extern void free_packet(io_packet_t*);
|
|
|
|
extern endpoint_t* endpoint_get(void);
|
|
extern int endpoint_init(endpoint_t*, int, int, int, int);
|
|
extern int endpoint_connect(endpoint_t*, char*, int);
|
|
extern int endpoint_accept(endpoint_t*, endpoint_t*);
|
|
extern int endpoint_set_conn_handler(endpoint_t*, conn_handler_t);
|
|
extern int endpoint_enq(endpoint_t*, data_item_t*);
|
|
extern data_item_t* endpoint_deq(endpoint_t*);
|
|
extern uint64_t endpoint_getseq(endpoint_t*);
|
|
extern void endpoint_block_tasks(endpoint_t*);
|
|
extern void endpoint_unblock_tasks(endpoint_t*);
|
|
extern int endpoint_is_task_blocked(endpoint_t*);
|
|
extern int endpoint_set_owner(endpoint_t*, void*);
|
|
extern int endpoint_set_msg_handler(endpoint_t*, msg_handler_t);
|
|
extern int endpoint_set_err_handler(endpoint_t*, err_handler_t);
|
|
extern int endpoint_set_on_connected(endpoint_t*, void (*cb)(endpoint_t *));
|
|
extern void endpoint_fini(endpoint_t*);
|
|
extern int endpoint_set_peer(endpoint_t*, xce_peerinfo_t*);
|
|
|
|
extern int io_fsm_start(io_fsm_t*, io_packet_t*);
|
|
|
|
extern void initialize_openssl(void);
|
|
extern void cleanup_openssl(void);
|
|
extern SSL_CTX* create_ssl_context(char*, char*);
|
|
extern void iomgr_set_ssl_ctx(iomgr_t*, SSL_CTX*);
|
|
|
|
extern int iomgr_init(iomgr_t*);
|
|
extern int iomgr_monitor(endpoint_t*);
|
|
extern int iomgr_unmonitor(iomgr_t*, endpoint_t*);
|
|
extern int iomgr_start(iomgr_t*);
|
|
extern int iomgr_fini(iomgr_t*);
|
|
extern int iomgr_stop(iomgr_t*);
|
|
#endif
|