move flush_init() etc. from defer service clients to the
bounce daemon?
+ Is it practical to move errors from global dict_errno
+ to lookuphandle->dict_errno?
+
Either make all void dict_* operations return an error code,
or require that they reset dict_errno on entry, either exit
with a fatal error or set dict_errno on error.
it is remote (type memcache: or proxy:). This does not work
because memcache can use a non-proxied file as backup).
- Is it possible to replace msg_fatal calls in match_ops.c
- by msg_warn and longjmp? The callers will have to specify
- if they want the code to return instead of terminate.
-
Things to do after the stable release:
What is the feasibility of adding an mta_name (personality)
return;
/*
- * Update the backup database first.
+ * Update the memcache first.
+ */
+ dict_memcache_set(dict_mc, value, dict_mc->mc_ttl);
+
+ /*
+ * Update the backup database last.
*/
if (dict_mc->backup) {
dict_errno = 0;
backup_errno = dict_errno;
}
- /*
- * Update the memcache last.
- */
- dict_memcache_set(dict_mc, value, dict_mc->mc_ttl);
-
if (msg_verbose)
msg_info("%s: %s: update key \"%s\"(%s) => \"%s\" %s",
myname, dict_mc->dict.name, name, STR(dict_mc->key_buf),
const char *myname = "dict_memcache_delete";
DICT_MC *dict_mc = (DICT_MC *) dict;
int backup_errno = 0;
- int del_res = 0;
- int mem_res;
+ int del_res;
/*
* Skip lookups with an inapplicable key, silently. This is just deleting
return (1);
/*
- * Update the persistent database first.
+ * Update the memcache first.
+ */
+ del_res = dict_memcache_del(dict_mc);
+
+ /*
+ * Update the persistent database last.
*/
if (dict_mc->backup) {
dict_errno = 0;
backup_errno = dict_errno;
}
- /*
- * Update the memcache last.
- */
- mem_res = dict_memcache_del(dict_mc);
-
if (msg_verbose)
msg_info("%s: %s: delete key \"%s\"(%s) => %s",
myname, dict_mc->dict.name, name, STR(dict_mc->key_buf),
dict_errno = (dict_mc->backup ? backup_errno : dict_mc->mc_errno);
- return (dict_mc->backup ? del_res : mem_res);
+ return (del_res);
}
/* dict_memcache_sequence - first/next lookup */
* Patches change both the patchlevel and the release date. Snapshots have no
* patchlevel; they change the release date only.
*/
-#define MAIL_RELEASE_DATE "20111222"
+#define MAIL_RELEASE_DATE "20111224"
#define MAIL_VERSION_NUMBER "2.9"
#ifdef SNAPSHOT
dict_flags_str(request_flags & DICT_FLAG_INST_MASK));
if (msg_verbose)
msg_info("proxy_map_find: %s", STR(map_type_name_flags));
- if ((dict = dict_handle(STR(map_type_name_flags))) == 0)
+ if ((dict = dict_handle(STR(map_type_name_flags))) == 0) {
dict = dict_open(map_type_name, proxy_writer ?
WRITE_OPEN_FLAGS : READ_OPEN_FLAGS,
request_flags);
- if (dict == 0)
- msg_panic("proxy_map_find: dict_open null result");
- dict_register(STR(map_type_name_flags), dict);
+ if (dict == 0)
+ msg_panic("proxy_map_find: dict_open null result");
+ dict_register(STR(map_type_name_flags), dict);
+ }
+ dict_errno = 0;
return (dict);
}
dict->flags = ((dict->flags & ~DICT_FLAG_RQST_MASK)
| (request_flags & DICT_FLAG_RQST_MASK)
| DICT_FLAG_SYNC_UPDATE | DICT_FLAG_DUP_REPLACE);
- dict_errno = 0;
dict_put(dict, STR(request_key), STR(request_value));
reply_status = (dict_errno ? PROXY_STAT_RETRY : PROXY_STAT_OK);
}
dict->flags = ((dict->flags & ~DICT_FLAG_RQST_MASK)
| (request_flags & DICT_FLAG_RQST_MASK)
| DICT_FLAG_SYNC_UPDATE);
- dict_errno = 0;
dict_status = dict_del(dict, STR(request_key));
reply_status = (dict_status == 0 ? PROXY_STAT_OK :
dict_status > 0 ? PROXY_STAT_NOKEY :
if (loop_count > loop_max) {
msg_warn("resolve_addr: <%s>: giving up after %ld iterations",
addr, (long) loop_count);
+ *flags |= RESOLVE_FLAG_FAIL;
+ FREE_MEMORY_AND_RETURN;
break;
}
DICT_FLAG_LOCK | DICT_FLAG_FOLD_FIX
| DICT_FLAG_NO_REGSUB);
tp->wildcard_channel = tp->wildcard_nexthop = 0;
- tp->transport_errno = 0;
+ tp->wildcard_errno = 0;
tp->expire = 0;
return (tp);
}
#define PARTIAL DICT_FLAG_FIXED
if (find_transport_entry(tp, WILDCARD, "", FULL, channel, nexthop)) {
- tp->transport_errno = 0;
+ tp->wildcard_errno = 0;
tp->wildcard_channel = channel;
tp->wildcard_nexthop = nexthop;
if (msg_verbose)
msg_info("wildcard_{chan:hop}={%s:%s}",
vstring_str(channel), vstring_str(nexthop));
} else {
- tp->transport_errno = dict_errno;
+ tp->wildcard_errno = dict_errno;
vstring_free(channel);
vstring_free(nexthop);
tp->wildcard_channel = 0;
/*
* Fall back to the wild-card entry.
*/
- if (tp->transport_errno || event_time() > tp->expire)
+ if (tp->wildcard_errno || event_time() > tp->expire)
transport_wildcard_init(tp);
- if (tp->transport_errno) {
- dict_errno = tp->transport_errno;
+ if (tp->wildcard_errno) {
+ dict_errno = tp->wildcard_errno;
return (NOTFOUND);
} else if (tp->wildcard_channel) {
update_entry(STR(tp->wildcard_channel), STR(tp->wildcard_nexthop),
MAPS *transport_path;
VSTRING *wildcard_channel;
VSTRING *wildcard_nexthop;
- int transport_errno;
+ int wildcard_errno;
time_t expire;
} TRANSPORT_INFO;