From f76cb52eb5d65ff8c5948e550768983c9548d8fe Mon Sep 17 00:00:00 2001 From: Martin Schwenke Date: Wed, 2 Mar 2016 16:06:58 +1100 Subject: [PATCH] ctdb-killtcp: Factor out ctdb_killtcp() This function knows nothing about CTDB contexts or VNNs, so it can be used elsewhere. Signed-off-by: Martin Schwenke Reviewed-by: Amitay Isaacs --- ctdb/server/ctdb_takeover.c | 132 +++++++++++++++++++++--------------- 1 file changed, 77 insertions(+), 55 deletions(-) diff --git a/ctdb/server/ctdb_takeover.c b/ctdb/server/ctdb_takeover.c index 9c356943873..100fb95040f 100644 --- a/ctdb/server/ctdb_takeover.c +++ b/ctdb/server/ctdb_takeover.c @@ -2850,48 +2850,30 @@ static void *add_killtcp_callback(void *parm, void *data) return parm; } -/* - add a tcp socket to the list of connections we want to RST - */ -static int ctdb_killtcp_add_connection(struct ctdb_context *ctdb, - ctdb_sock_addr *s, - ctdb_sock_addr *d) +/* Add a TCP socket to the list of connections we want to RST. The + * list is attached to *killtcp_arg. If this is NULL then allocate + * the structure. */ +static int ctdb_killtcp(struct tevent_context *ev, + TALLOC_CTX *mem_ctx, + const char *iface, + const ctdb_sock_addr *src, + const ctdb_sock_addr *dst, + struct ctdb_kill_tcp **killtcp_arg) { - ctdb_sock_addr src, dst; struct ctdb_kill_tcp *killtcp; struct ctdb_killtcp_con *con; - struct ctdb_vnn *vnn; - const char *iface; - struct ctdb_killtcp_destructor_data *dd; - - ctdb_canonicalize_ip(s, &src); - ctdb_canonicalize_ip(d, &dst); - vnn = find_public_ip_vnn(ctdb, &dst); - if (vnn == NULL) { - vnn = find_public_ip_vnn(ctdb, &src); - } - if (vnn == NULL) { - /* if it is not a public ip it could be our 'single ip' */ - if (ctdb->single_ip_vnn) { - if (ctdb_same_ip(&ctdb->single_ip_vnn->public_address, &dst)) { - vnn = ctdb->single_ip_vnn; - } - } - } - if (vnn == NULL) { - DEBUG(DEBUG_ERR,(__location__ " Could not killtcp, not a public address\n")); + if (killtcp_arg == NULL) { + DEBUG(DEBUG_ERR, (__location__ " killtcp_arg is NULL!\n")); return -1; } - iface = ctdb_vnn_iface_string(vnn); - killtcp = vnn->killtcp; + killtcp = *killtcp_arg; - /* If this is the first connection to kill we must allocate - a new structure - */ + /* Allocate a new structure if necessary. The structure is + * only freed when mem_ctx is freed. */ if (killtcp == NULL) { - killtcp = talloc_zero(vnn, struct ctdb_kill_tcp); + killtcp = talloc_zero(mem_ctx, struct ctdb_kill_tcp); if (killtcp == NULL) { DEBUG(DEBUG_ERR, (__location__ " out of memory\n")); return -1; @@ -2899,12 +2881,9 @@ static int ctdb_killtcp_add_connection(struct ctdb_context *ctdb, killtcp->capture_fd = -1; killtcp->connections = trbt_create(killtcp, 0); - - vnn->killtcp = killtcp; + *killtcp_arg = killtcp; } - - /* create a structure that describes this connection we want to RST and store it in killtcp->connections */ @@ -2913,32 +2892,36 @@ static int ctdb_killtcp_add_connection(struct ctdb_context *ctdb, DEBUG(DEBUG_ERR, (__location__ " out of memory\n")); return -1; } - con->src_addr = src; - con->dst_addr = dst; + con->src_addr = *src; + con->dst_addr = *dst; con->count = 0; con->killtcp = killtcp; trbt_insertarray32_callback(killtcp->connections, - KILLTCP_KEYLEN, killtcp_key(&con->dst_addr, &con->src_addr), - add_killtcp_callback, con); + KILLTCP_KEYLEN, + killtcp_key(&con->dst_addr, + &con->src_addr), + add_killtcp_callback, con); - /* + /* If we don't have a socket to listen on yet we must create it */ if (killtcp->capture_fd == -1) { - killtcp->capture_fd = ctdb_sys_open_capture_socket(iface, &killtcp->private_data); + killtcp->capture_fd = + ctdb_sys_open_capture_socket(iface, + &killtcp->private_data); if (killtcp->capture_fd == -1) { DEBUG(DEBUG_CRIT,(__location__ " Failed to open capturing " "socket on iface '%s' for killtcp (%s)\n", iface, strerror(errno))); - goto failed; + return -1; } } if (killtcp->fde == NULL) { - killtcp->fde = tevent_add_fd(ctdb->ev, killtcp, + killtcp->fde = tevent_add_fd(ev, killtcp, killtcp->capture_fd, TEVENT_FD_READ, capture_tcp_handler, killtcp); @@ -2947,7 +2930,7 @@ static int ctdb_killtcp_add_connection(struct ctdb_context *ctdb, /* We also need to set up some events to tickle all these connections until they are all reset */ - tevent_add_timer(ctdb->ev, killtcp, timeval_current_ofs(1, 0), + tevent_add_timer(ev, killtcp, timeval_current_ofs(1, 0), ctdb_tickle_sentenced_connections, killtcp); } @@ -2957,23 +2940,62 @@ static int ctdb_killtcp_add_connection(struct ctdb_context *ctdb, &con->src_addr, 0, 0, 0); - dd = talloc(killtcp, struct ctdb_killtcp_destructor_data); + return 0; +} + +/* + add a tcp socket to the list of connections we want to RST + */ +static int ctdb_killtcp_add_connection(struct ctdb_context *ctdb, + ctdb_sock_addr *s, + ctdb_sock_addr *d) +{ + ctdb_sock_addr src, dst; + struct ctdb_vnn *vnn; + const char *iface; + struct ctdb_killtcp_destructor_data *dd; + int ret; + + ctdb_canonicalize_ip(s, &src); + ctdb_canonicalize_ip(d, &dst); + + vnn = find_public_ip_vnn(ctdb, &dst); + if (vnn == NULL) { + vnn = find_public_ip_vnn(ctdb, &src); + } + if (vnn == NULL) { + /* if it is not a public ip it could be our 'single ip' */ + if (ctdb->single_ip_vnn) { + if (ctdb_same_ip(&ctdb->single_ip_vnn->public_address, &dst)) { + vnn = ctdb->single_ip_vnn; + } + } + } + if (vnn == NULL) { + DEBUG(DEBUG_ERR,(__location__ " Could not killtcp, not a public address\n")); + return -1; + } + + iface = ctdb_vnn_iface_string(vnn); + + ret = ctdb_killtcp(ctdb->ev, vnn, iface, &src, &dst, &vnn->killtcp); + if (ret != 0) { + return -1; + } + + dd = talloc(vnn->killtcp, struct ctdb_killtcp_destructor_data); if (dd == NULL) { DEBUG(DEBUG_ERR, (__location__ " out of memory\n")); - goto failed; + TALLOC_FREE(vnn->killtcp); + return -1; } dd->vnn = vnn; dd->ctdb = ctdb; - killtcp->destructor_data = dd; - talloc_set_destructor(killtcp, ctdb_killtcp_destructor); + vnn->killtcp->destructor_data = dd; + talloc_set_destructor(vnn->killtcp, ctdb_killtcp_destructor); return 0; - -failed: - talloc_free(vnn->killtcp); - vnn->killtcp = NULL; - return -1; } /* -- 2.47.3