summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordefanor <defanor@uberspace.net>2020-11-30 17:56:44 +0300
committerdefanor <defanor@uberspace.net>2020-11-30 17:56:44 +0300
commit5b5f109824b08619b9167cc82a8b56072a1ed477 (patch)
tree5c1b3a91cc6bf95b43072383b3ed4f1c72320674
parent3bcb471cf3fbe628e33ca4c2ab1419f8790499bb (diff)
Reconnect on "reset" and "system-shutdown" stream errors
-rw-r--r--README6
-rw-r--r--src/rexmpp.c25
-rw-r--r--src/rexmpp.h4
3 files changed, 25 insertions, 10 deletions
diff --git a/README b/README
index 61e39e6..5b4d422 100644
--- a/README
+++ b/README
@@ -23,8 +23,8 @@ A rough roadmap:
- Basic protocol:
-[+] XMPP core (RFC 6120). A prototype is mostly ready, though it can
- use more of error handling and refinement.
+[+] XMPP core (RFC 6120). Mostly ready, though would be nice to
+ review and refactor.
- Reliable and predictable message delivery:
@@ -38,7 +38,7 @@ A rough roadmap:
[+] "Happy Eyeballs" (RFC 8305).
[+] XEP-0368 v1.1: SRV records for XMPP over TLS.
-[+] SOCKS5 (RFC 1928) support. Implemented, though can be improved.
+[+] SOCKS5 (RFC 1928) support. Implemented, though no authentication.
[+] XEP-0199 v2.0: XMPP Ping.
[.] Certificate verification using DANE (experimental).
diff --git a/src/rexmpp.c b/src/rexmpp.c
index 2594089..0857209 100644
--- a/src/rexmpp.c
+++ b/src/rexmpp.c
@@ -1091,9 +1091,12 @@ rexmpp_err_t rexmpp_recv (rexmpp_t *s) {
}
rexmpp_log(s, LOG_INFO, "TCP disconnected");
rexmpp_cleanup(s);
- s->tcp_state = REXMPP_TCP_CLOSED;
- if (s->stream_state == REXMPP_STREAM_READY) {
+ if (s->stream_state == REXMPP_STREAM_READY ||
+ s->stream_state == REXMPP_STREAM_ERROR_RECONNECT) {
+ s->tcp_state = REXMPP_TCP_NONE;
rexmpp_schedule_reconnect(s);
+ } else {
+ s->tcp_state = REXMPP_TCP_CLOSED;
}
} else {
if (s->tls_state == REXMPP_TLS_ACTIVE) {
@@ -2054,9 +2057,18 @@ rexmpp_err_t rexmpp_process_element (rexmpp_t *s, xmlNodePtr elem) {
/* Stream errors, https://tools.ietf.org/html/rfc6120#section-4.9 */
if (rexmpp_xml_match(elem, "http://etherx.jabber.org/streams",
"error")) {
- rexmpp_log(s, LOG_ERR, "stream error");
- s->stream_state = REXMPP_STREAM_ERROR;
- return REXMPP_E_STREAM;
+ if (rexmpp_xml_find_child(elem, "urn:ietf:params:xml:ns:xmpp-streams",
+ "reset") != NULL ||
+ rexmpp_xml_find_child(elem, "urn:ietf:params:xml:ns:xmpp-streams",
+ "system-shutdown") != NULL) {
+ rexmpp_log(s, LOG_WARNING, "Server reset or shutdown.");
+ s->stream_state = REXMPP_STREAM_ERROR_RECONNECT;
+ return REXMPP_E_AGAIN;
+ } else {
+ rexmpp_log(s, LOG_ERR, "Stream error");
+ s->stream_state = REXMPP_STREAM_ERROR;
+ return REXMPP_E_STREAM;
+ }
}
/* STARTTLS negotiation,
@@ -2503,7 +2515,8 @@ rexmpp_err_t rexmpp_run (rexmpp_t *s, fd_set *read_fds, fd_set *write_fds) {
}
}
- if (s->tcp_state == REXMPP_TCP_CLOSED) {
+ if (s->tcp_state == REXMPP_TCP_CLOSED &&
+ s->stream_state != REXMPP_STREAM_ERROR_RECONNECT) {
rexmpp_console_on_run(s, REXMPP_SUCCESS);
return REXMPP_SUCCESS;
} else {
diff --git a/src/rexmpp.h b/src/rexmpp.h
index bd6f8cb..2f21fce 100644
--- a/src/rexmpp.h
+++ b/src/rexmpp.h
@@ -112,7 +112,9 @@ enum stream_st {
/** The server-to-client stream is closed. */
REXMPP_STREAM_CLOSED,
/** A stream error was detected in the server-to-client stream. */
- REXMPP_STREAM_ERROR
+ REXMPP_STREAM_ERROR,
+ /** A stream error that should be fixed by a reconnect. */
+ REXMPP_STREAM_ERROR_RECONNECT
};
/** @brief TLS state */