diff --git a/sr_port/gtm_repl.h b/sr_port/gtm_repl.h index bde2eb44f..e3d9b8219 100644 --- a/sr_port/gtm_repl.h +++ b/sr_port/gtm_repl.h @@ -3,6 +3,9 @@ * Copyright (c) 2013-2016 Fidelity National Information * * Services, Inc. and/or its subsidiaries. All rights reserved. * * * + * Copyright (c) 2018 YottaDB LLC. and/or its subsidiaries. * + * All rights reserved. * + * * * This source code contains the intellectual property * * of its copyright holder(s), and is made available * * under a license. If you do not know the terms of * @@ -48,22 +51,66 @@ error_def(ERR_TLSCLOSE); #define DEFAULT_RENEGOTIATE_TIMEOUT (2 * 60) /* About 2 hours between renegotiation. */ #define MIN_RENEGOTIATE_TIMEOUT 1 -#define REPLTLS_SET_NEXT_RENEGOTIATE_HRTBT(NEXT_RENEG_HRTBT) \ -{ \ - if (0 < gtmsource_options.renegotiate_interval) \ - { \ - repl_tls.renegotiate_state = REPLTLS_WAITING_FOR_RENEG_TIMEOUT; \ - TIMEOUT_DONE_NOCH(NEXT_RENEG_HRTBT); \ - TIMEOUT_INIT_NOCH(NEXT_RENEG_HRTBT, gtmsource_options.renegotiate_interval * MILLISECS_IN_SEC); \ - } \ -} +#define REPLTLS_SET_NEXT_RENEGOTIATE_HRTBT(NEXT_RENEG_HRTBT) \ +MBSTART { \ + if (0 < gtmsource_options.renegotiate_interval) \ + { \ + repl_tls.renegotiate_state = REPLTLS_WAITING_FOR_RENEG_TIMEOUT; \ + TIMEOUT_DONE_NOCH(NEXT_RENEG_HRTBT); \ + TIMEOUT_INIT_NOCH(NEXT_RENEG_HRTBT, gtmsource_options.renegotiate_interval * MILLISECS_IN_SEC); \ + } \ +} MBEND + +#define ISSUE_REPLNOTLS(ERRID, STR1, STR2) \ +MBSTART { \ + if (!PLAINTEXT_FALLBACK) \ + rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERRID, 4, LEN_AND_LIT(STR1), LEN_AND_LIT(STR2)); \ + gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(6) MAKE_MSG_WARNING(ERRID), 4, LEN_AND_LIT(STR1), LEN_AND_LIT(STR2)); \ +} MBEND + +/* The GTMSOURCE_HANDLE_TLSIOERROR and GTMRECV_HANDLE_TLSIOERROR macros handle an error from the TLS/SSL layer. + * They check if plaintext fallback is specified by the user and if so, close the current connection and fall + * back to non-tls (i.e. non-encrypted) communication or replication. If plaintext fallback is not specified, + * then issue a TLSIOERROR error and terminate the caller replication server (source or receiver server). + */ +#define GTMSOURCE_HANDLE_TLSIOERROR(SEND_OR_RECV) \ +MBSTART { \ + assert(repl_tls.enabled); \ + if (!PLAINTEXT_FALLBACK) \ + rts_error_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_TLSIOERROR, 2, LEN_AND_LIT(SEND_OR_RECV), \ + ERR_TEXT, 2, LEN_AND_STR(gtm_tls_get_error())); \ + else \ + { /* Fall back from TLS to Plaintext */ \ + gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(8) \ + MAKE_MSG_WARNING(ERR_TLSIOERROR), 2, LEN_AND_LIT(SEND_OR_RECV), \ + ERR_TEXT, 2, LEN_AND_STR(gtm_tls_get_error())); \ + repl_log(gtmsource_log_fp, TRUE, TRUE, \ + "Plaintext fallback enabled. Closing and reconnecting without TLS/SSL.\n"); \ + repl_close(>msource_sock_fd); \ + SHORT_SLEEP(GTMSOURCE_WAIT_FOR_RECEIVER_CLOSE_CONN); \ + gtmsource_state = gtmsource_local->gtmsource_state = GTMSOURCE_WAITING_FOR_CONNECTION; \ + CLEAR_REPL_TLS_REQUESTED; /* As if -tlsid qualifier was never specified. */ \ + } \ +} MBEND -#define ISSUE_REPLNOTLS(ERRID, STR1, STR2) \ -{ \ - if (!PLAINTEXT_FALLBACK) \ - rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERRID, 4, LEN_AND_LIT(STR1), LEN_AND_LIT(STR2)); \ - gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(6) MAKE_MSG_WARNING(ERRID), 4, LEN_AND_LIT(STR1), LEN_AND_LIT(STR2)); \ -} +#define GTMRECV_HANDLE_TLSIOERROR(SEND_OR_RECV) \ +MBSTART { \ + assert(repl_tls.enabled); \ + if (!PLAINTEXT_FALLBACK) \ + rts_error_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_TLSIOERROR, 2, LEN_AND_LIT(SEND_OR_RECV), \ + ERR_TEXT, 2, LEN_AND_STR(gtm_tls_get_error())); \ + else \ + { /* Fall back from TLS to Plaintext */ \ + gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(8) \ + MAKE_MSG_WARNING(ERR_TLSIOERROR), 2, LEN_AND_LIT(SEND_OR_RECV), \ + ERR_TEXT, 2, LEN_AND_STR(gtm_tls_get_error())); \ + repl_log(gtmrecv_log_fp, TRUE, TRUE, \ + "Plaintext fallback enabled. Closing and reconnecting without TLS/SSL.\n"); \ + repl_close(>mrecv_sock_fd); \ + repl_connection_reset = TRUE; \ + CLEAR_REPL_TLS_REQUESTED; /* As if -tlsid qualifier was never specified. */ \ + } \ +} MBEND void repl_log_tls_info(FILE *logfp, gtm_tls_socket_t *socket); int repl_do_tls_handshake(FILE *logfp, int sock_fd, boolean_t do_accept, int *poll_direction); diff --git a/sr_port/repl_comm.c b/sr_port/repl_comm.c index 0d5b868ab..08ef60584 100644 --- a/sr_port/repl_comm.c +++ b/sr_port/repl_comm.c @@ -238,11 +238,11 @@ int repl_send(int sock_fd, unsigned char *buff, int *send_len, int timeout GTMTL /* handle error */ save_errno = repl_tls.enabled ? gtm_tls_errno() : ERRNO; if (-1 == save_errno) - { /* This indicates an error from TLS/SSL layer and not from a system call. */ + { /* This indicates an error from TLS/SSL layer and not from a system call. + * Set error status to ERR_TLSIOERROR and let caller handle it appropriately. + */ assert(repl_tls.enabled); - assert(FALSE); - rts_error_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_TLSIOERROR, 2, LEN_AND_LIT("send"), ERR_TEXT, 2, - LEN_AND_STR(gtm_tls_get_error())); + save_errno = ERR_TLSIOERROR; } # else save_errno = ERRNO; @@ -347,11 +347,12 @@ int repl_recv(int sock_fd, unsigned char *buff, int *recv_len, int timeout GTMTL /* handle error */ save_errno = repl_tls.enabled ? gtm_tls_errno() : ERRNO; if (-1 == save_errno) - { + { /* This indicates an error from TLS/SSL layer and not from a system call. + * Set error status to ERR_TLSIOERROR and let caller handle it appropriately. + */ assert(repl_tls.enabled); - assert(FALSE); - rts_error_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_TLSIOERROR, 2, LEN_AND_LIT("recv"), ERR_TEXT, 2, - LEN_AND_STR(gtm_tls_get_error())); + save_errno = ERR_TLSIOERROR; + bytes_recvd = -1; /* to ensure "save_errno" does not get overwritten a few lines later */ } # else save_errno = ERRNO; diff --git a/sr_unix/gtmrecv_fetchresync.c b/sr_unix/gtmrecv_fetchresync.c index 538a5af02..996c346f7 100755 --- a/sr_unix/gtmrecv_fetchresync.c +++ b/sr_unix/gtmrecv_fetchresync.c @@ -62,6 +62,7 @@ #include "repl_instance.h" #include "gtmio.h" #include "replgbl.h" +#include "gtm_repl.h" #define MAX_ATTEMPTS_FOR_FETCH_RESYNC 60 /* max-wait in seconds for source server response after connection is established */ #define MAX_WAIT_FOR_FETCHRESYNC_CONN 60 /* max-wait in seconds to establish connection with the source server */ @@ -72,14 +73,24 @@ if (SS_NORMAL != STATUS) \ { \ if (EREPL_RECV == repl_errno) \ + { /* Note that no check for TLSIOERROR is needed here since the fetchresync rollback \ + * currently never connects with a source server using TLS. \ + */ \ + assert(ERR_TLSIOERROR != STATUS); \ rts_error_csa(CSA_ARG(NULL) VARLSTCNT(7) ERR_REPLCOMM, 0, ERR_TEXT, 2, \ LEN_AND_LIT("Error in recv() for " MESSAGE), STATUS); /* BYPASSOK(recv) */ \ - else if (EREPL_SEND == repl_errno) \ + } else if (EREPL_SEND == repl_errno) \ + { /* Note that no check for TLSIOERROR is needed here since the fetchresync rollback \ + * currently never connects with a source server using TLS. \ + */ \ + assert(ERR_TLSIOERROR != STATUS); \ rts_error_csa(CSA_ARG(NULL) VARLSTCNT(7) ERR_REPLCOMM, 0, ERR_TEXT, 2, \ LEN_AND_LIT("Error in send() for " MESSAGE), STATUS); /* BYPASSOK(send) */ \ - else if (EREPL_SELECT == repl_errno) \ + } else if (EREPL_SELECT == repl_errno) \ rts_error_csa(CSA_ARG(NULL) VARLSTCNT(7) ERR_REPLCOMM, 0, ERR_TEXT, 2, \ LEN_AND_LIT("Error in select() for " MESSAGE), STATUS); \ + else \ + assert(FALSE); \ } \ if (0 >= WAIT_COUNT) \ rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_REPLCOMM, 0, ERR_TEXT, 2, \ @@ -236,6 +247,7 @@ int gtmrecv_fetchresync(int port, seq_num *resync_seqno, seq_num max_reg_seqno) rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_REPLCOMM); return ERR_REPLCOMM; } + assert(!REPL_TLS_ENABLED); /* Currently, a fetchresync rollback never uses TLS to connect to the source server */ /* Wait for REPL_RESYNC_SEQNO (if dual-site primary) or REPL_OLD_NEED_INSTANCE_INFO (if multi-site primary) * or REPL_NEED_INSTINFO (if multi-site primary with supplementary instance support) message */ diff --git a/sr_unix/gtmrecv_poll_actions.c b/sr_unix/gtmrecv_poll_actions.c index e6819f2e1..4e394c652 100644 --- a/sr_unix/gtmrecv_poll_actions.c +++ b/sr_unix/gtmrecv_poll_actions.c @@ -267,18 +267,30 @@ int gtmrecv_poll_actions1(int *pending_data_len, int *buff_unprocessed, unsigned ; /* Empty Body */ if (SS_NORMAL != status) { - if (REPL_CONN_RESET(status) && EREPL_SEND == repl_errno) + if (EREPL_SEND == repl_errno) { - repl_log(gtmrecv_log_fp, TRUE, TRUE, "Connection reset while sending XOFF_ACK_ME. " - "Status = %d ; %s\n", status, STRERROR(status)); - REPL_CLOSE_CONNECTION(gtmrecv_sock_fd, repl_connection_reset, curr_conn_state, \ - gtmrecv_send_cmp2uncmp); +# ifdef GTM_TLS + if (ERR_TLSIOERROR == status) + { /* Note that both GTMRECV_HANDLE_TLSIOERROR and REPL_CLOSE_CONNECTION do a + * "repl_close" but that is okay since "repl_close" is a no-op in the second call. + */ + GTMRECV_HANDLE_TLSIOERROR("send"); + REPL_CLOSE_CONNECTION(gtmrecv_sock_fd, repl_connection_reset, curr_conn_state, \ + gtmrecv_send_cmp2uncmp); + } else +# endif + if (REPL_CONN_RESET(status)) + { + repl_log(gtmrecv_log_fp, TRUE, TRUE, "Connection reset while sending XOFF_ACK_ME. " + "Status = %d ; %s\n", status, STRERROR(status)); + REPL_CLOSE_CONNECTION(gtmrecv_sock_fd, repl_connection_reset, curr_conn_state, \ + gtmrecv_send_cmp2uncmp); - } else if (EREPL_SEND == repl_errno) - rts_error_csa(CSA_ARG(NULL) VARLSTCNT(7) ERR_REPLCOMM, 0, ERR_TEXT, 2, - LEN_AND_LIT("Error sending XOFF msg due to BAD_TRANS or UPD crash/shutdown. " - "Error in send"), status); - else + } else + rts_error_csa(CSA_ARG(NULL) VARLSTCNT(7) ERR_REPLCOMM, 0, + ERR_TEXT, 2, LEN_AND_LIT("Error sending XOFF msg due to BAD_TRANS or UPD" + " crash/shutdown. Error in send"), status); + } else { assert(EREPL_SELECT == repl_errno); rts_error_csa(CSA_ARG(NULL) VARLSTCNT(7) ERR_REPLCOMM, 0, ERR_TEXT, 2, @@ -415,6 +427,17 @@ int gtmrecv_poll_actions1(int *pending_data_len, int *buff_unprocessed, unsigned { if (EREPL_RECV == repl_errno) { +# ifdef GTM_TLS + if (ERR_TLSIOERROR == status) + { /* Note that both GTMRECV_HANDLE_TLSIOERROR and REPL_CLOSE_CONNECTION do a "repl_close" + * but that is okay since "repl_close" returns as a no-op in the second call. + */ + GTMRECV_HANDLE_TLSIOERROR("recv"); + REPL_CLOSE_CONNECTION(gtmrecv_sock_fd, repl_connection_reset, curr_conn_state, \ + gtmrecv_send_cmp2uncmp); + return_status = STOP_POLL; + } else +# endif if (REPL_CONN_RESET(status)) { repl_log(gtmrecv_log_fp, TRUE, TRUE, "Connection reset while receiving XOFF_ACK. " @@ -464,24 +487,37 @@ int gtmrecv_poll_actions1(int *pending_data_len, int *buff_unprocessed, unsigned curr_conn_state.send_seqno); } else { - if (REPL_CONN_RESET(status) && EREPL_SEND == repl_errno) + if (EREPL_SEND == repl_errno) { - if (curr_conn_state.send_cmp2uncmp) - { - repl_log(gtmrecv_log_fp, TRUE, TRUE, "Connection reset while sending REPL_CMP2UNCMP. " - "Status = %d ; %s\n", status, STRERROR(status)); +# ifdef GTM_TLS + if (ERR_TLSIOERROR == status) + { /* Note that both GTMRECV_HANDLE_TLSIOERROR and REPL_CLOSE_CONNECTION do a + * "repl_close" but that is okay since "repl_close" is a no-op in the second call. + */ + GTMRECV_HANDLE_TLSIOERROR("send"); + REPL_CLOSE_CONNECTION(gtmrecv_sock_fd, repl_connection_reset, curr_conn_state, \ + gtmrecv_send_cmp2uncmp); + return_status = STOP_POLL; } else +# endif + if (REPL_CONN_RESET(status)) { - repl_log(gtmrecv_log_fp, TRUE, TRUE, "Connection reset while sending REPL_BADTRANS. " - "Status = %d ; %s\n", status, STRERROR(status)); - } - REPL_CLOSE_CONNECTION(gtmrecv_sock_fd, repl_connection_reset, curr_conn_state, \ - gtmrecv_send_cmp2uncmp); - return_status = STOP_POLL; - } else if (EREPL_SEND == repl_errno) - rts_error_csa(CSA_ARG(NULL) VARLSTCNT(7) ERR_REPLCOMM, 0, ERR_TEXT, 2, - LEN_AND_LIT("Error sending REPL_BADTRANS/REPL_CMP2UNCMP. Error in send"), status); - else + if (curr_conn_state.send_cmp2uncmp) + { + repl_log(gtmrecv_log_fp, TRUE, TRUE, "Connection reset while sending REPL_CMP2UNCMP. " + "Status = %d ; %s\n", status, STRERROR(status)); + } else + { + repl_log(gtmrecv_log_fp, TRUE, TRUE, "Connection reset while sending REPL_BADTRANS. " + "Status = %d ; %s\n", status, STRERROR(status)); + } + REPL_CLOSE_CONNECTION(gtmrecv_sock_fd, repl_connection_reset, curr_conn_state, \ + gtmrecv_send_cmp2uncmp); + return_status = STOP_POLL; + } else + rts_error_csa(CSA_ARG(NULL) VARLSTCNT(7) ERR_REPLCOMM, 0, ERR_TEXT, 2, + LEN_AND_LIT("Error sending REPL_BADTRANS/REPL_CMP2UNCMP. Error in send"), status); + } else { assert(EREPL_SELECT == repl_errno); rts_error_csa(CSA_ARG(NULL) VARLSTCNT(7) ERR_REPLCOMM, 0, ERR_TEXT, 2, diff --git a/sr_unix/gtmrecv_process.c b/sr_unix/gtmrecv_process.c index 03fd59213..90e183ceb 100644 --- a/sr_unix/gtmrecv_process.c +++ b/sr_unix/gtmrecv_process.c @@ -392,21 +392,31 @@ STATICFNDEF void gtmrecv_repl_send_loop_error(int status, char *msgtypestr) char print_msg[1024]; assert((EREPL_SEND == repl_errno) || (EREPL_SELECT == repl_errno)); - if (REPL_CONN_RESET(status) && EREPL_SEND == repl_errno) + if (EREPL_SEND == repl_errno) { - repl_log(gtmrecv_log_fp, TRUE, TRUE, "Connection got reset while sending %s message. Status = %d ; %s\n", - msgtypestr, status, STRERROR(status)); - repl_connection_reset = TRUE; - repl_close(>mrecv_sock_fd); - SNPRINTF(print_msg, SIZEOF(print_msg), "Closing connection on receiver side\n"); - repl_log(gtmrecv_log_fp, TRUE, TRUE, print_msg); - gtm_event_log(GTM_EVENT_LOG_ARGC, "MUPIP", "ERR_REPLWARN", print_msg); - return; - } else if (EREPL_SEND == repl_errno) - { - SNPRINTF(print_msg, SIZEOF(print_msg), "Error sending %s message. Error in send : %s", - msgtypestr, STRERROR(status)); - rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_REPLCOMM, 0, ERR_TEXT, 2, LEN_AND_STR(print_msg)); +# ifdef GTM_TLS + if (ERR_TLSIOERROR == status) + { + GTMRECV_HANDLE_TLSIOERROR("send"); + return; + } else +# endif + if (REPL_CONN_RESET(status)) + { + repl_log(gtmrecv_log_fp, TRUE, TRUE, "Connection got reset while sending %s message. Status = %d ; %s\n", + msgtypestr, status, STRERROR(status)); + repl_connection_reset = TRUE; + repl_close(>mrecv_sock_fd); + SNPRINTF(print_msg, SIZEOF(print_msg), "Closing connection on receiver side\n"); + repl_log(gtmrecv_log_fp, TRUE, TRUE, print_msg); + gtm_event_log(GTM_EVENT_LOG_ARGC, "MUPIP", "ERR_REPLWARN", print_msg); + return; + } else + { + SNPRINTF(print_msg, SIZEOF(print_msg), "Error sending %s message. Error in send : %s", + msgtypestr, STRERROR(status)); + rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_REPLCOMM, 0, ERR_TEXT, 2, LEN_AND_STR(print_msg)); + } } else if (EREPL_SELECT == repl_errno) { SNPRINTF(print_msg, SIZEOF(print_msg), "Error sending %s message. Error in select : %s", @@ -2881,6 +2891,13 @@ STATICFNDEF void do_main_loop(boolean_t crash_restart) { if (EREPL_RECV == repl_errno) { +# ifdef GTM_TLS + if (ERR_TLSIOERROR == status) + { + GTMRECV_HANDLE_TLSIOERROR("recv"); + return; + } else +# endif if (REPL_CONN_RESET(status)) { repl_log(gtmrecv_log_fp, TRUE, TRUE, "Connection reset. Status = %d ; %s\n", @@ -2894,7 +2911,7 @@ STATICFNDEF void do_main_loop(boolean_t crash_restart) } } else if (EREPL_SELECT == repl_errno) { - ISSUE_REPLCOMM_ERROR("Error in receiving from source. Error in select", status); + ISSUE_REPLCOMM_ERROR("Error in receiving from source. Error in select", status); } } if (repl_connection_reset) diff --git a/sr_unix/gtmsource_heartbeat.c b/sr_unix/gtmsource_heartbeat.c index 3f6583b4f..e8b75a43b 100755 --- a/sr_unix/gtmsource_heartbeat.c +++ b/sr_unix/gtmsource_heartbeat.c @@ -3,6 +3,9 @@ * Copyright (c) 2006-2017 Fidelity National Information * * Services, Inc. and/or its subsidiaries. All rights reserved. * * * + * Copyright (c) 2018 YottaDB LLC. and/or its subsidiaries. * + * All rights reserved. * + * * * This source code contains the intellectual property * * of its copyright holder(s), and is made available * * under a license. If you do not know the terms of * @@ -41,6 +44,7 @@ #include "gt_timer.h" #include "gtmsource_heartbeat.h" #include "relqop.h" +#include "gtm_repl.h" GBLREF jnlpool_addrs_ptr_t jnlpool; GBLREF int gtmsource_sock_fd; @@ -200,18 +204,26 @@ int gtmsource_send_heartbeat(time_t *now) return (SS_NORMAL); } - if (EREPL_SEND == repl_errno && REPL_CONN_RESET(status)) - { - repl_log(gtmsource_log_fp, TRUE, TRUE, "Connection reset while attempting to send heartbeat. Status = %d ; %s\n", - status, STRERROR(status)); - repl_close(>msource_sock_fd); - gtmsource_state = jnlpool->gtmsource_local->gtmsource_state = GTMSOURCE_WAITING_FOR_CONNECTION; - return (SS_NORMAL); - } if (EREPL_SEND == repl_errno) - rts_error_csa(CSA_ARG(NULL) VARLSTCNT(7) ERR_REPLCOMM, 0, ERR_TEXT, 2, - LEN_AND_LIT("Error sending HEARTBEAT message. Error in send"), status); - if (EREPL_SELECT == repl_errno) + { +# ifdef GTM_TLS + if (ERR_TLSIOERROR == status) + { + GTMSOURCE_HANDLE_TLSIOERROR("send"); + return (SS_NORMAL); + } else +# endif + if (REPL_CONN_RESET(status)) + { + repl_log(gtmsource_log_fp, TRUE, TRUE, "Connection reset while attempting to send heartbeat. Status = %d ; %s\n", + status, STRERROR(status)); + repl_close(>msource_sock_fd); + gtmsource_state = jnlpool->gtmsource_local->gtmsource_state = GTMSOURCE_WAITING_FOR_CONNECTION; + return (SS_NORMAL); + } else + rts_error_csa(CSA_ARG(NULL) VARLSTCNT(7) ERR_REPLCOMM, 0, ERR_TEXT, 2, + LEN_AND_LIT("Error sending HEARTBEAT message. Error in send"), status); + } else if (EREPL_SELECT == repl_errno) rts_error_csa(CSA_ARG(NULL) VARLSTCNT(7) ERR_REPLCOMM, 0, ERR_TEXT, 2, LEN_AND_LIT("Error sending HEARTBEAT message. Error in select"), status); assertpro((SS_NORMAL == status)); diff --git a/sr_unix/gtmsource_process.c b/sr_unix/gtmsource_process.c index 961c825b5..dfaca7d3c 100644 --- a/sr_unix/gtmsource_process.c +++ b/sr_unix/gtmsource_process.c @@ -619,6 +619,13 @@ void gtmsource_recv_ctl(void) { if (EREPL_RECV == repl_errno) { +# ifdef GTM_TLS + if (ERR_TLSIOERROR == status) + { + GTMSOURCE_HANDLE_TLSIOERROR("recv"); + return; + } else +# endif if (REPL_CONN_RESET(status)) { /* Connection reset */ @@ -830,6 +837,13 @@ int gtmsource_process(void) { if (EREPL_RECV == repl_errno) { +# ifdef GTM_TLS + if (ERR_TLSIOERROR == status) + { + GTMSOURCE_HANDLE_TLSIOERROR("recv"); + continue; + } else +# endif if (REPL_CONN_RESET(status)) { /* Connection reset */ repl_log(gtmsource_log_fp, TRUE, TRUE, @@ -848,6 +862,13 @@ int gtmsource_process(void) } } else if (EREPL_SEND == repl_errno) { +# ifdef GTM_TLS + if (ERR_TLSIOERROR == status) + { + GTMSOURCE_HANDLE_TLSIOERROR("send"); + continue; + } else +# endif if (REPL_CONN_RESET(status)) { repl_log(gtmsource_log_fp, TRUE, TRUE, @@ -1700,26 +1721,36 @@ int gtmsource_process(void) gtmsource_flush_fh(post_read_seqno); if (GTMSOURCE_HANDLE_ONLN_RLBK == gtmsource_state) break; /* the outerloop will continue */ - if (REPL_CONN_RESET(status) && EREPL_SEND == repl_errno) - { - repl_log(gtmsource_log_fp, TRUE, TRUE, - "Connection reset while sending seqno data from " - INT8_FMT" "INT8_FMTX" to "INT8_FMT" "INT8_FMTX - ". Status = %d ; %s\n", pre_read_seqno, pre_read_seqno, - post_read_seqno, post_read_seqno, status, STRERROR(status)); - repl_close(>msource_sock_fd); - SHORT_SLEEP(GTMSOURCE_WAIT_FOR_RECEIVER_CLOSE_CONN); - gtmsource_state = gtmsource_local->gtmsource_state - = GTMSOURCE_WAITING_FOR_CONNECTION; - break; - } if (EREPL_SEND == repl_errno) { - SNPRINTF(err_string, SIZEOF(err_string), - "Error sending DATA. Error in send : %s", STRERROR(status)); - rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_REPLCOMM, 0, ERR_TEXT, 2, - LEN_AND_STR(err_string)); +# ifdef GTM_TLS + if (ERR_TLSIOERROR == status) + { + GTMSOURCE_HANDLE_TLSIOERROR("send"); + break; + } else +# endif + if (REPL_CONN_RESET(status)) + { + repl_log(gtmsource_log_fp, TRUE, TRUE, + "Connection reset while sending seqno data from " + INT8_FMT" "INT8_FMTX" to "INT8_FMT" "INT8_FMTX + ". Status = %d ; %s\n", pre_read_seqno, pre_read_seqno, + post_read_seqno, post_read_seqno, status, STRERROR(status)); + repl_close(>msource_sock_fd); + SHORT_SLEEP(GTMSOURCE_WAIT_FOR_RECEIVER_CLOSE_CONN); + gtmsource_state = gtmsource_local->gtmsource_state + = GTMSOURCE_WAITING_FOR_CONNECTION; + break; + } else + { + SNPRINTF(err_string, SIZEOF(err_string), + "Error sending DATA. Error in send : %s", STRERROR(status)); + rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_REPLCOMM, 0, + ERR_TEXT, 2, LEN_AND_STR(err_string)); + } } + assert(EREPL_SELECT == repl_errno); if (EREPL_SELECT == repl_errno) { SNPRINTF(err_string, SIZEOF(err_string), diff --git a/sr_unix/gtmsource_process_ops.c b/sr_unix/gtmsource_process_ops.c index cd7dd925b..f5344efb3 100644 --- a/sr_unix/gtmsource_process_ops.c +++ b/sr_unix/gtmsource_process_ops.c @@ -1003,6 +1003,7 @@ void gtmsource_repl_send(repl_msg_ptr_t msg, char *msgtypestr, seq_num optional_ int tosend_len, sent_len, sent_this_iter; /* needed for REPL_SEND_LOOP */ int status, poll_dir; /* needed for REPL_{SEND,RECV}_LOOP */ char err_string[1024]; + gtmsource_local_ptr_t gtmsource_local; assert((REPL_MULTISITE_MSG_START > msg->type) || (REPL_PROTO_VER_MULTISITE <= remote_side->proto_ver)); if (MAX_SEQNO != optional_seqno) @@ -1024,22 +1025,32 @@ void gtmsource_repl_send(repl_msg_ptr_t msg, char *msgtypestr, seq_num optional_ /* Check for error status from the REPL_SEND */ if (SS_NORMAL != status) { - if (REPL_CONN_RESET(status) && EREPL_SEND == repl_errno) - { - repl_log(gtmsource_log_fp, TRUE, TRUE, "Connection reset while sending %s. Status = %d ; %s\n", - msgtypestr, status, STRERROR(status)); - repl_close(>msource_sock_fd); - SHORT_SLEEP(GTMSOURCE_WAIT_FOR_RECEIVER_CLOSE_CONN); - gtmsource_state = jnlpool->gtmsource_local->gtmsource_state = GTMSOURCE_WAITING_FOR_CONNECTION; - return; - } + assert((EREPL_SEND == repl_errno) || (EREPL_SELECT == repl_errno)); if (EREPL_SEND == repl_errno) { - SNPRINTF(err_string, SIZEOF(err_string), "Error sending %s message. " - "Error in send : %s", msgtypestr, STRERROR(status)); - rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_REPLCOMM, 0, ERR_TEXT, 2, LEN_AND_STR(err_string)); - } - if (EREPL_SELECT == repl_errno) +# ifdef GTM_TLS + if (ERR_TLSIOERROR == status) + { + gtmsource_local = jnlpool->gtmsource_local; /* needed by GTMSOURCE_HANDLE_TLSIOERROR */ + GTMSOURCE_HANDLE_TLSIOERROR("send"); + return; + } else +# endif + if (REPL_CONN_RESET(status)) + { + repl_log(gtmsource_log_fp, TRUE, TRUE, "Connection reset while sending %s. Status = %d ; %s\n", + msgtypestr, status, STRERROR(status)); + repl_close(>msource_sock_fd); + SHORT_SLEEP(GTMSOURCE_WAIT_FOR_RECEIVER_CLOSE_CONN); + gtmsource_state = jnlpool->gtmsource_local->gtmsource_state = GTMSOURCE_WAITING_FOR_CONNECTION; + return; + } else + { + SNPRINTF(err_string, SIZEOF(err_string), "Error sending %s message. " + "Error in send : %s", msgtypestr, STRERROR(status)); + rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_REPLCOMM, 0, ERR_TEXT, 2, LEN_AND_STR(err_string)); + } + } else if (EREPL_SELECT == repl_errno) { SNPRINTF(err_string, SIZEOF(err_string), "Error sending %s message. " "Error in select : %s", msgtypestr, STRERROR(status)); @@ -1069,6 +1080,7 @@ static boolean_t gtmsource_repl_recv(repl_msg_ptr_t msg, int4 msglen, int4 msgty char err_string[1024]; unsigned char *buff; int4 bufflen; + gtmsource_local_ptr_t gtmsource_local; repl_log(gtmsource_log_fp, TRUE, FALSE, "Waiting for %s message\n", msgtypestr); assert((REPL_XOFF != msgtype) && (REPL_XON != msgtype) && (REPL_XOFF_ACK_ME != msgtype)); @@ -1100,6 +1112,14 @@ static boolean_t gtmsource_repl_recv(repl_msg_ptr_t msg, int4 msglen, int4 msgty { if (EREPL_RECV == repl_errno) { +# ifdef GTM_TLS + if (ERR_TLSIOERROR == status) + { + gtmsource_local = jnlpool->gtmsource_local; /* needed by GTMSOURCE_HANDLE_TLSIOERROR */ + GTMSOURCE_HANDLE_TLSIOERROR("recv"); + return FALSE; + } else +# endif if (REPL_CONN_RESET(status)) { /* Connection reset */ repl_log(gtmsource_log_fp, TRUE, TRUE,