diff --git a/src/connection.c b/src/connection.c index da23996..93f35e8 100644 --- a/src/connection.c +++ b/src/connection.c @@ -30,6 +30,8 @@ static SSL_CTX *SSL_init_context(void); int link_add_untrusted(void *ls, X509 *cert); #endif +int cn_is_in_error(connection_t *cn); + static int cn_want_write(connection_t *cn); static int connection_timedout(connection_t *cn); static int socket_set_nonblock(int s); @@ -55,7 +57,7 @@ void connection_close(connection_t *cn) { mylog(LOG_DEBUG, "Connection close asked. FD:%d ", (long)cn->handle); - if (cn->connected != CONN_DISCONN && cn->connected != CONN_ERROR) { + if (cn->connected != CONN_DISCONN) { cn->connected = CONN_DISCONN; if (close(cn->handle) == -1) mylog(LOG_WARN, "Error on socket close: %s", @@ -178,7 +180,7 @@ static void connect_trynext(connection_t *cn) cn->handle = -1; } - cn->connected = CONN_ERROR; + cn->connected = CONN_DISCONN; connecting_data_free(cn->connecting_data); cn->connecting_data = NULL; mylog(LOG_ERROR, "connect() failed."); @@ -278,7 +280,6 @@ static int _write_socket(connection_t *cn, char *message) if (cn_is_connected(cn)) { if (errno != EPIPE) mylog(LOG_INFO, "Broken socket: %s.", strerror(errno)); - connection_close(cn); cn->connected = CONN_ERROR; } mylog(LOG_DEBUGVERB, "write: %d, %s", cn->handle, strerror(errno)); @@ -287,6 +288,8 @@ static int _write_socket(connection_t *cn, char *message) static int write_socket(connection_t *cn, char *line) { + if (cn_is_in_error(cn)) + return WRITE_ERROR; #ifdef HAVE_LIBSSL if (cn->ssl) return _write_socket_SSL(cn, line); @@ -918,7 +921,7 @@ static void create_socket(char *dsthostname, char *dstport, char *srchostname, hint.ai_socktype = SOCK_STREAM; hint.ai_protocol = 0; - cn->connected = CONN_ERROR; + cn->connected = CONN_DISCONN; cdata = (struct connecting_data *) bip_malloc(sizeof(struct connecting_data)); cdata->dst = cdata->src = cdata->cur = NULL; @@ -967,7 +970,7 @@ static void create_listening_socket(char *hostname, char *port, .ai_next = 0 }; - cn->connected = CONN_ERROR; + cn->connected = CONN_DISCONN; err = getaddrinfo(hostname, port, &hint, &res); if (err) { @@ -1026,7 +1029,7 @@ static void create_listening_socket(char *hostname, char *port, } freeaddrinfo(res); mylog(LOG_ERROR, "Unable to bind/listen"); - cn->connected = CONN_ERROR; + cn->connected = CONN_DISCONN; } static connection_t *connection_init(int anti_flood, int ssl, int timeout, @@ -1437,7 +1440,6 @@ static int SSLize(connection_t *cn, int *nc) if (err2 == SSL_ERROR_ZERO_RETURN || err2 == SSL_ERROR_SSL) { mylog(LOG_ERROR, "Error in SSL handshake."); connection_close(cn); - cn->connected = CONN_ERROR; return 1; } /* Here are unhandled errors/resource waiting. Timeout must be diff --git a/src/connection.h b/src/connection.h index 5fa7d2e..34ae0d0 100644 --- a/src/connection.h +++ b/src/connection.h @@ -78,7 +78,7 @@ typedef struct connection { list_t *outgoing; char *partial; list_t *incoming_lines; - void *user_data; + void *user_data; /* struct link_any* */ struct connecting_data *connecting_data; #ifdef HAVE_LIBSSL SSL_CTX *ssl_ctx_h; diff --git a/src/irc.c b/src/irc.c index 59e3e54..fe39004 100644 --- a/src/irc.c +++ b/src/irc.c @@ -2481,6 +2481,8 @@ void bip_on_event(bip_t *bip, connection_t *conn) goto prot_err_lines; } int r; + /* XXX irc_dispatch doesn't return an error when a write call encounter + * a WRITE_ERROR: return value of real_write_all function isn't checked */ r = irc_dispatch(bip, lc, line); irc_line_free(line); free(line_s); @@ -2494,7 +2496,8 @@ void bip_on_event(bip_t *bip, connection_t *conn) /* XXX: not real error */ if (r == OK_CLOSE) goto prot_err_lines; - + if (conn->connected == CONN_ERROR) + goto prot_err_lines; } list_free(linel); return;