]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-dns: If existing dns connection dies in write(), retry connect once.
authorTimo Sirainen <tss@iki.fi>
Sat, 23 Nov 2013 16:35:08 +0000 (18:35 +0200)
committerTimo Sirainen <tss@iki.fi>
Sat, 23 Nov 2013 16:35:08 +0000 (18:35 +0200)
src/lib-dns/dns-lookup.c

index b8f7380e58b7b08a5a6f873e0ee8e8112a3a3454..70d2b163247710507d57de5991ebf70cd1a664bf 100644 (file)
@@ -302,6 +302,28 @@ int dns_client_connect(struct dns_client *client, const char **error_r)
        return 0;
 }
 
+static int
+dns_client_send_request(struct dns_client *client, const char *cmd,
+                       const char **error_r)
+{
+       int ret;
+
+       if (client->fd == -1) {
+               if (dns_client_connect(client, error_r) < 0)
+                       return -1;
+               ret = -1;
+       } else {
+               /* already connected. if write() fails, retry connecting */
+               ret = 0;
+       }
+
+       if (write_full(client->fd, cmd, strlen(cmd)) < 0) {
+               *error_r = t_strdup_printf("write(%s) failed: %m", client->path);
+               return ret;
+       }
+       return 1;
+}
+
 static int
 dns_client_lookup_common(struct dns_client *client,
                         const char *cmd, bool ptr_lookup,
@@ -310,20 +332,20 @@ dns_client_lookup_common(struct dns_client *client,
 {
        struct dns_lookup *lookup;
        struct dns_lookup_result result;
+       int ret;
 
        memset(&result, 0, sizeof(result));
        result.ret = EAI_FAIL;
 
-       if (dns_client_connect(client, &result.error) < 0) {
-               callback(&result, context);
-               return -1;
-       }
-       if (write_full(client->fd, cmd, strlen(cmd)) < 0) {
-               result.error = t_strdup_printf("write(%s) failed: %m",
-                                              client->path);
-               dns_client_disconnect(client, result.error);
-               callback(&result, context);
-               return -1;
+       if ((ret = dns_client_send_request(client, cmd, &result.error)) <= 0) {
+               if (ret == 0) {
+                       /* retry once */
+                       ret = dns_client_send_request(client, cmd, &result.error);
+               }
+               if (ret <= 0) {
+                       callback(&result, context);
+                       return -1;
+               }
        }
 
        lookup = i_new(struct dns_lookup, 1);