diff options
Diffstat (limited to 'ctdb')
-rw-r--r-- | ctdb/include/ctdb_private.h | 5 | ||||
-rw-r--r-- | ctdb/takeover/ctdb_takeover.c | 2 | ||||
-rw-r--r-- | ctdb/takeover/system.c | 15 |
3 files changed, 16 insertions, 6 deletions
diff --git a/ctdb/include/ctdb_private.h b/ctdb/include/ctdb_private.h index bce24343af..7f1c5e30c6 100644 --- a/ctdb/include/ctdb_private.h +++ b/ctdb/include/ctdb_private.h @@ -981,8 +981,9 @@ int ctdb_ctrl_get_public_ips(struct ctdb_context *ctdb, /* from takeover/system.c */ int ctdb_sys_send_arp(const struct sockaddr_in *saddr, const char *iface); bool ctdb_sys_have_ip(const char *ip); -int ctdb_sys_send_ack(const struct sockaddr_in *dest, - const struct sockaddr_in *src); +int ctdb_sys_send_tcp(const struct sockaddr_in *dest, + const struct sockaddr_in *src, + uint32_t seq, uint32_t ack, int rst); int ctdb_set_public_addresses(struct ctdb_context *ctdb, const char *alist); int ctdb_set_event_script(struct ctdb_context *ctdb, const char *script); diff --git a/ctdb/takeover/ctdb_takeover.c b/ctdb/takeover/ctdb_takeover.c index 7f84eaedaa..14d4adaae7 100644 --- a/ctdb/takeover/ctdb_takeover.c +++ b/ctdb/takeover/ctdb_takeover.c @@ -83,7 +83,7 @@ static void ctdb_control_send_arp(struct event_context *ev, struct timed_event * (unsigned)ntohs(tcp->daddr.sin_port), inet_ntoa(tcp->saddr.sin_addr), (unsigned)ntohs(tcp->saddr.sin_port))); - ret = ctdb_sys_send_ack(&tcp->saddr, &tcp->daddr); + ret = ctdb_sys_send_tcp(&tcp->saddr, &tcp->daddr, 0, 0, 0); if (ret != 0) { DEBUG(0,(__location__ " Failed to send tcp tickle ack for %s\n", inet_ntoa(tcp->saddr.sin_addr))); diff --git a/ctdb/takeover/system.c b/ctdb/takeover/system.c index 7cd4dbcc7d..74a860a918 100644 --- a/ctdb/takeover/system.c +++ b/ctdb/takeover/system.c @@ -174,15 +174,19 @@ static uint16_t tcp_checksum(uint16_t *data, size_t n, struct iphdr *ip) } /* - send tcp ack packet from the specified IP/port to the specified + Send tcp segment from the specified IP/port to the specified destination IP/port. This is used to trigger the receiving host into sending its own ACK, which should trigger early detection of TCP reset by the client after IP takeover + + This can also be used to send RST segments (if rst is true) and also + if correct seq and ack numbers are provided. */ -int ctdb_sys_send_ack(const struct sockaddr_in *dest, - const struct sockaddr_in *src) +int ctdb_sys_send_tcp(const struct sockaddr_in *dest, + const struct sockaddr_in *src, + uint32_t seq, uint32_t ack, int rst) { int s, ret; uint32_t one = 1; @@ -224,7 +228,12 @@ int ctdb_sys_send_ack(const struct sockaddr_in *dest, pkt.tcp.source = src->sin_port; pkt.tcp.dest = dest->sin_port; + pkt.tcp.seq = seq; + pkt.tcp.ack_seq = ack; pkt.tcp.ack = 1; + if (rst) { + pkt.tcp.rst = 1; + } pkt.tcp.doff = sizeof(pkt.tcp)/4; pkt.tcp.window = htons(1234); pkt.tcp.check = tcp_checksum((uint16_t *)&pkt.tcp, sizeof(pkt.tcp), &pkt.ip); |