Postfix3.3.1
qmgr.h
[詳解]
1 /*++
2 /* NAME
3 /* qmgr 3h
4 /* SUMMARY
5 /* queue manager data structures
6 /* SYNOPSIS
7 /* #include "qmgr.h"
8 /* DESCRIPTION
9 /* .nf
10 
11  /*
12  * System library.
13  */
14 #include <sys/time.h>
15 #include <time.h>
16 
17  /*
18  * Utility library.
19  */
20 #include <vstream.h>
21 #include <scan_dir.h>
22 
23  /*
24  * Global library.
25  */
26 #include <recipient_list.h>
27 #include <dsn.h>
28 
29  /*
30  * The queue manager is built around lots of mutually-referring structures.
31  * These typedefs save some typing.
32  */
34 typedef struct QMGR_QUEUE QMGR_QUEUE;
35 typedef struct QMGR_ENTRY QMGR_ENTRY;
36 typedef struct QMGR_MESSAGE QMGR_MESSAGE;
37 typedef struct QMGR_JOB QMGR_JOB;
38 typedef struct QMGR_PEER QMGR_PEER;
44 typedef struct QMGR_SCAN QMGR_SCAN;
46 
47  /*
48  * Hairy macros to update doubly-linked lists.
49  */
50 #define QMGR_LIST_ROTATE(head, object, peers) { \
51  head.next->peers.prev = head.prev; \
52  head.prev->peers.next = head.next; \
53  head.next = object->peers.next; \
54  head.next->peers.prev = 0; \
55  head.prev = object; \
56  object->peers.next = 0; \
57 }
58 
59 #define QMGR_LIST_UNLINK(head, type, object, peers) { \
60  type _next = object->peers.next; \
61  type _prev = object->peers.prev; \
62  if (_prev) _prev->peers.next = _next; \
63  else head.next = _next; \
64  if (_next) _next->peers.prev = _prev; \
65  else head.prev = _prev; \
66  object->peers.next = object->peers.prev = 0; \
67 }
68 
69 #define QMGR_LIST_LINK(head, pred, object, succ, peers) { \
70  object->peers.prev = pred; \
71  object->peers.next = succ; \
72  if (pred) pred->peers.next = object; \
73  else head.next = object; \
74  if (succ) succ->peers.prev = object; \
75  else head.prev = object; \
76 }
77 
78 #define QMGR_LIST_PREPEND(head, object, peers) { \
79  object->peers.next = head.next; \
80  object->peers.prev = 0; \
81  if (head.next) { \
82  head.next->peers.prev = object; \
83  } else { \
84  head.prev = object; \
85  } \
86  head.next = object; \
87 }
88 
89 #define QMGR_LIST_APPEND(head, object, peers) { \
90  object->peers.prev = head.prev; \
91  object->peers.next = 0; \
92  if (head.prev) { \
93  head.prev->peers.next = object; \
94  } else { \
95  head.next = object; \
96  } \
97  head.prev = object; \
98 }
99 
100 #define QMGR_LIST_INIT(head) { \
101  head.prev = 0; \
102  head.next = 0; \
103 }
104 
105  /*
106  * Transports are looked up by name (when we have resolved a message), or
107  * round-robin wise (when we want to distribute resources fairly).
108  */
109 struct QMGR_TRANSPORT_LIST {
112 };
113 
114 extern struct HTABLE *qmgr_transport_byname; /* transport by name */
115 extern QMGR_TRANSPORT_LIST qmgr_transport_list; /* transports, round robin */
116 
117  /*
118  * Delivery agents provide feedback, as hints that Postfix should expend
119  * more or fewer resources on a specific destination domain. The main.cf
120  * file specifies how feedback affects delivery concurrency: add/subtract a
121  * constant, a ratio of constants, or a constant divided by the delivery
122  * concurrency; and it specifies how much feedback must accumulate between
123  * concurrency updates.
124  */
125 struct QMGR_FEEDBACK {
126  int hysteresis; /* to pass, need to be this tall */
127  double base; /* pre-computed from main.cf */
128  int index; /* none, window, sqrt(window) */
129 };
130 
131 #define QMGR_FEEDBACK_IDX_NONE 0 /* no window dependence */
132 #define QMGR_FEEDBACK_IDX_WIN 1 /* 1/window dependence */
133 #if 0
134 #define QMGR_FEEDBACK_IDX_SQRT_WIN 2 /* 1/sqrt(window) dependence */
135 #endif
136 
137 #ifdef QMGR_FEEDBACK_IDX_SQRT_WIN
138 #include <math.h>
139 #endif
140 
141 extern void qmgr_feedback_init(QMGR_FEEDBACK *, const char *, const char *, const char *, const char *);
142 
143 #ifndef QMGR_FEEDBACK_IDX_SQRT_WIN
144 #define QMGR_FEEDBACK_VAL(fb, win) \
145  ((fb).index == QMGR_FEEDBACK_IDX_NONE ? (fb).base : (fb).base / (win))
146 #else
147 #define QMGR_FEEDBACK_VAL(fb, win) \
148  ((fb).index == QMGR_FEEDBACK_IDX_NONE ? (fb).base : \
149  (fb).index == QMGR_FEEDBACK_IDX_WIN ? (fb).base / (win) : \
150  (fb).base / sqrt(win))
151 #endif
152 
153  /*
154  * Each transport (local, smtp-out, bounce) can have one queue per next hop
155  * name. Queues are looked up by next hop name (when we have resolved a
156  * message destination), or round-robin wise (when we want to deliver
157  * messages fairly).
158  */
159 struct QMGR_QUEUE_LIST {
160  QMGR_QUEUE *next;
161  QMGR_QUEUE *prev;
162 };
163 
167 };
168 
169 struct QMGR_TRANSPORT {
170  int flags; /* blocked, etc. */
171  int pending; /* incomplete DA connections */
172  char *name; /* transport name */
173  int dest_concurrency_limit; /* concurrency per domain */
174  int init_dest_concurrency; /* init. per-domain concurrency */
175  int recipient_limit; /* recipients per transaction */
176  int rcpt_per_stack; /* extra slots reserved for jobs put
177  * on the job stack */
178  int rcpt_unused; /* available in-core recipient slots */
179  int refill_limit; /* recipient batch size for message
180  * refill */
181  int refill_delay; /* delay before message refill */
182  int slot_cost; /* cost of new preemption slot (# of
183  * selected entries) */
184  int slot_loan; /* preemption boost offset and */
185  int slot_loan_factor; /* factor, see qmgr_job_preempt() */
186  int min_slots; /* when preemption can take effect at
187  * all */
188  struct HTABLE *queue_byname; /* queues indexed by domain */
189  QMGR_QUEUE_LIST queue_list; /* queues, round robin order */
190  struct HTABLE *job_byname; /* jobs indexed by queue id */
191  QMGR_JOB_LIST job_list; /* list of message jobs (1 per
192  * message) ordered by scheduler */
193  QMGR_JOB_LIST job_bytime; /* jobs ordered by time since queued */
194  QMGR_JOB *job_current; /* keeps track of the current job */
195  QMGR_JOB *job_next_unread; /* next job with unread recipients */
196  QMGR_JOB *candidate_cache; /* cached result from
197  * qmgr_job_candidate() */
198  QMGR_JOB *candidate_cache_current; /* current job tied to the candidate */
199  time_t candidate_cache_time; /* when candidate_cache was last
200  * updated */
201  int blocker_tag; /* for marking blocker jobs */
202  QMGR_TRANSPORT_LIST peers; /* linkage */
203  DSN *dsn; /* why unavailable */
204  QMGR_FEEDBACK pos_feedback; /* positive feedback control */
205  QMGR_FEEDBACK neg_feedback; /* negative feedback control */
206  int fail_cohort_limit; /* flow shutdown control */
207  int xport_rate_delay; /* suspend per delivery */
208  int rate_delay; /* suspend per delivery */
209 };
210 
211 #define QMGR_TRANSPORT_STAT_DEAD (1<<1)
212 #define QMGR_TRANSPORT_STAT_RATE_LOCK (1<<2)
213 
217 extern void qmgr_transport_throttle(QMGR_TRANSPORT *, DSN *);
219 extern QMGR_TRANSPORT *qmgr_transport_create(const char *);
220 extern QMGR_TRANSPORT *qmgr_transport_find(const char *);
221 
222 #define QMGR_TRANSPORT_THROTTLED(t) ((t)->flags & QMGR_TRANSPORT_STAT_DEAD)
223 
224  /*
225  * Each next hop (e.g., a domain name) has its own queue of pending message
226  * transactions. The "todo" queue contains messages that are to be delivered
227  * to this next hop. When a message is elected for transmission, it is moved
228  * from the "todo" queue to the "busy" queue. Messages are taken from the
229  * "todo" queue in round-robin order.
230  */
231 struct QMGR_ENTRY_LIST {
232  QMGR_ENTRY *next;
233  QMGR_ENTRY *prev;
234 };
235 
236 struct QMGR_QUEUE {
237  int dflags; /* delivery request options */
238  time_t last_done; /* last delivery completion */
239  char *name; /* domain name or address */
240  char *nexthop; /* domain name */
241  int todo_refcount; /* queue entries (todo list) */
242  int busy_refcount; /* queue entries (busy list) */
243  int window; /* slow open algorithm */
244  double success; /* accumulated positive feedback */
245  double failure; /* accumulated negative feedback */
246  double fail_cohorts; /* pseudo-cohort failure count */
247  QMGR_TRANSPORT *transport; /* transport linkage */
248  QMGR_ENTRY_LIST todo; /* todo queue entries */
249  QMGR_ENTRY_LIST busy; /* messages on the wire */
250  QMGR_QUEUE_LIST peers; /* neighbor queues */
251  DSN *dsn; /* why unavailable */
252  time_t clog_time_to_warn; /* time of last warning */
253  int blocker_tag; /* tagged if blocks job list */
254 };
255 
256 #define QMGR_QUEUE_TODO 1 /* waiting for service */
257 #define QMGR_QUEUE_BUSY 2 /* recipients on the wire */
258 
259 extern int qmgr_queue_count;
260 
261 extern QMGR_QUEUE *qmgr_queue_create(QMGR_TRANSPORT *, const char *, const char *);
262 extern void qmgr_queue_done(QMGR_QUEUE *);
263 extern void qmgr_queue_throttle(QMGR_QUEUE *, DSN *);
264 extern void qmgr_queue_unthrottle(QMGR_QUEUE *);
265 extern QMGR_QUEUE *qmgr_queue_find(QMGR_TRANSPORT *, const char *);
266 extern void qmgr_queue_suspend(QMGR_QUEUE *, int);
267 
268  /*
269  * Exclusive queue states. Originally there were only two: "throttled" and
270  * "not throttled". It was natural to encode these in the queue window size.
271  * After 10 years it's not practical to rip out all the working code and
272  * change representations, so we just clean up the names a little.
273  *
274  * Note: only the "ready" state can reach every state (including itself);
275  * non-ready states can reach only the "ready" state. Other transitions are
276  * forbidden, because they would result in dangling event handlers.
277  */
278 #define QMGR_QUEUE_STAT_THROTTLED 0 /* back-off timer */
279 #define QMGR_QUEUE_STAT_SUSPENDED -1 /* voluntary delay timer */
280 #define QMGR_QUEUE_STAT_SAVED -2 /* delayed cleanup timer */
281 #define QMGR_QUEUE_STAT_BAD -3 /* can't happen */
282 
283 #define QMGR_QUEUE_READY(q) ((q)->window > 0)
284 #define QMGR_QUEUE_THROTTLED(q) ((q)->window == QMGR_QUEUE_STAT_THROTTLED)
285 #define QMGR_QUEUE_SUSPENDED(q) ((q)->window == QMGR_QUEUE_STAT_SUSPENDED)
286 #define QMGR_QUEUE_SAVED(q) ((q)->window == QMGR_QUEUE_STAT_SAVED)
287 #define QMGR_QUEUE_BAD(q) ((q)->window <= QMGR_QUEUE_STAT_BAD)
288 
289 #define QMGR_QUEUE_STATUS(q) ( \
290  QMGR_QUEUE_READY(q) ? "ready" : \
291  QMGR_QUEUE_THROTTLED(q) ? "throttled" : \
292  QMGR_QUEUE_SUSPENDED(q) ? "suspended" : \
293  QMGR_QUEUE_SAVED(q) ? "saved" : \
294  "invalid queue status" \
295  )
296 
297  /*
298  * Structure of one next-hop queue entry. In order to save some copying
299  * effort we allow multiple recipients per transaction.
300  */
301 struct QMGR_ENTRY {
302  VSTREAM *stream; /* delivery process */
303  QMGR_MESSAGE *message; /* message info */
304  RECIPIENT_LIST rcpt_list; /* as many as it takes */
305  QMGR_QUEUE *queue; /* parent linkage */
306  QMGR_PEER *peer; /* parent linkage */
307  QMGR_ENTRY_LIST queue_peers; /* per queue neighbor entries */
308  QMGR_ENTRY_LIST peer_peers; /* per peer neighbor entries */
309 };
310 
312 extern void qmgr_entry_unselect(QMGR_ENTRY *);
313 extern void qmgr_entry_move_todo(QMGR_QUEUE *, QMGR_ENTRY *);
314 extern void qmgr_entry_done(QMGR_ENTRY *, int);
316 
317  /*
318  * All common in-core information about a message is kept here. When all
319  * recipients have been tried the message file is linked to the "deferred"
320  * queue (some hosts not reachable), to the "bounce" queue (some recipients
321  * were rejected), and is then removed from the "active" queue.
322  */
323 struct QMGR_MESSAGE {
324  int flags; /* delivery problems */
325  int qflags; /* queuing flags */
326  int tflags; /* tracing flags */
327  long tflags_offset; /* offset for killing */
328  int rflags; /* queue file read flags */
329  VSTREAM *fp; /* open queue file or null */
330  int refcount; /* queue entries */
331  int single_rcpt; /* send one rcpt at a time */
332  struct timeval arrival_time; /* start of receive transaction */
333  time_t create_time; /* queue file create time */
334  struct timeval active_time; /* time of entry into active queue */
335  time_t queued_time; /* sanitized time when moved to the
336  * active queue */
337  time_t refill_time; /* sanitized time of last message
338  * refill */
339  long warn_offset; /* warning bounce flag offset */
340  time_t warn_time; /* time next warning to be sent */
341  long data_offset; /* data seek offset */
342  char *queue_name; /* queue name */
343  char *queue_id; /* queue file */
344  char *encoding; /* content encoding */
345  char *sender; /* complete address */
346  char *dsn_envid; /* DSN envelope ID */
347  int dsn_ret; /* DSN headers/full */
348  int smtputf8; /* requires unicode */
349  char *verp_delims; /* VERP delimiters */
350  char *filter_xport; /* filtering transport */
351  char *inspect_xport; /* inspecting transport */
352  char *redirect_addr; /* info@spammer.tld */
353  long data_size; /* data segment size */
354  long cont_length; /* message content length */
355  long rcpt_offset; /* more recipients here */
356  char *client_name; /* client hostname */
357  char *client_addr; /* client address */
358  char *client_port; /* client port */
359  char *client_proto; /* client protocol */
360  char *client_helo; /* helo parameter */
361  char *sasl_method; /* SASL method */
362  char *sasl_username; /* SASL user name */
363  char *sasl_sender; /* SASL sender */
364  char *log_ident; /* up-stream queue ID */
365  char *rewrite_context; /* address qualification */
366  RECIPIENT_LIST rcpt_list; /* complete addresses */
367  int rcpt_count; /* used recipient slots */
368  int rcpt_limit; /* maximum read in-core */
369  int rcpt_unread; /* # of recipients left in queue file */
370  QMGR_JOB_LIST job_list; /* jobs delivering this message (1
371  * per transport) */
372 };
373 
374  /*
375  * Flags 0-15 are reserved for qmgr_user.h.
376  */
377 #define QMGR_READ_FLAG_SEEN_ALL_NON_RCPT (1<<16)
378 
379 #define QMGR_MESSAGE_LOCKED ((QMGR_MESSAGE *) 1)
380 
381 extern int qmgr_message_count;
382 extern int qmgr_recipient_count;
383 extern int qmgr_vrfy_pend_count;
384 
385 extern void qmgr_message_free(QMGR_MESSAGE *);
387 extern void qmgr_message_kill_record(QMGR_MESSAGE *, long);
388 extern QMGR_MESSAGE *qmgr_message_alloc(const char *, const char *, int, mode_t);
390 
391 #define QMGR_MSG_STATS(stats, message) \
392  MSG_STATS_INIT2(stats, \
393  incoming_arrival, message->arrival_time, \
394  active_arrival, message->active_time)
395 
396  /*
397  * Sometimes it's required to access the transport queues and entries on per
398  * message basis. That's what the QMGR_JOB structure is for - it groups all
399  * per message information within each transport using a list of QMGR_PEER
400  * structures. These structures in turn correspond with per message
401  * QMGR_QUEUE structure and list all per message QMGR_ENTRY structures.
402  */
406 };
407 
408 struct QMGR_JOB {
409  QMGR_MESSAGE *message; /* message delivered by this job */
410  QMGR_TRANSPORT *transport; /* transport this job belongs to */
411  QMGR_JOB_LIST message_peers; /* per message neighbor linkage */
412  QMGR_JOB_LIST transport_peers; /* per transport neighbor linkage */
413  QMGR_JOB_LIST time_peers; /* by time neighbor linkage */
414  QMGR_JOB *stack_parent; /* stack parent */
415  QMGR_JOB_LIST stack_children; /* all stack children */
416  QMGR_JOB_LIST stack_siblings; /* stack children linkage */
417  int stack_level; /* job stack nesting level (-1 means
418  * it's not on the lists at all) */
419  int blocker_tag; /* tagged if blocks the job list */
420  struct HTABLE *peer_byname; /* message job peers, indexed by
421  * domain */
422  QMGR_PEER_LIST peer_list; /* list of message job peers */
423  int slots_used; /* slots used during preemption */
424  int slots_available; /* slots available for preemption (in
425  * multiples of slot_cost) */
426  int selected_entries; /* # of entries selected for delivery
427  * so far */
428  int read_entries; /* # of entries read in-core so far */
429  int rcpt_count; /* used recipient slots */
430  int rcpt_limit; /* available recipient slots */
431 };
432 
433 struct QMGR_PEER {
434  QMGR_JOB *job; /* job handling this peer */
435  QMGR_QUEUE *queue; /* queue corresponding with this peer */
436  int refcount; /* peer entries */
437  QMGR_ENTRY_LIST entry_list; /* todo message entries queued for
438  * this peer */
439  QMGR_PEER_LIST peers; /* neighbor linkage */
440 };
441 
444 extern void qmgr_job_blocker_update(QMGR_QUEUE *);
445 
447 extern void qmgr_job_free(QMGR_JOB *);
448 extern void qmgr_job_move_limits(QMGR_JOB *);
449 
453 extern void qmgr_peer_free(QMGR_PEER *);
454 
455  /*
456  * qmgr_defer.c
457  */
458 extern void qmgr_defer_transport(QMGR_TRANSPORT *, DSN *);
459 extern void qmgr_defer_todo(QMGR_QUEUE *, DSN *);
460 extern void qmgr_defer_recipient(QMGR_MESSAGE *, RECIPIENT *, DSN *);
461 
462  /*
463  * qmgr_bounce.c
464  */
465 extern void qmgr_bounce_recipient(QMGR_MESSAGE *, RECIPIENT *, DSN *);
466 
467  /*
468  * qmgr_deliver.c
469  */
470 extern int qmgr_deliver_concurrency;
471 extern void qmgr_deliver(QMGR_TRANSPORT *, VSTREAM *);
472 
473  /*
474  * qmgr_active.c
475  */
476 extern int qmgr_active_feed(QMGR_SCAN *, const char *);
477 extern void qmgr_active_drain(void);
478 extern void qmgr_active_done(QMGR_MESSAGE *);
479 
480  /*
481  * qmgr_move.c
482  */
483 extern void qmgr_move(const char *, const char *, time_t);
484 
485  /*
486  * qmgr_enable.c
487  */
488 extern void qmgr_enable_all(void);
490 extern void qmgr_enable_queue(QMGR_QUEUE *);
491 
492  /*
493  * Queue scan context.
494  */
495 struct QMGR_SCAN {
496  char *queue; /* queue name */
497  int flags; /* private, this run */
498  int nflags; /* private, next run */
499  struct SCAN_DIR *handle; /* scan */
500 };
501 
502  /*
503  * Flags that control queue scans or destination selection. These are
504  * similar to the QMGR_REQ_XXX request codes.
505  */
506 #define QMGR_SCAN_START (1<<0) /* start now/restart when done */
507 #define QMGR_SCAN_ALL (1<<1) /* all queue file time stamps */
508 #define QMGR_FLUSH_ONCE (1<<2) /* unthrottle once */
509 #define QMGR_FLUSH_DFXP (1<<3) /* override defer_transports */
510 #define QMGR_FLUSH_EACH (1<<4) /* unthrottle per message */
511 
512  /*
513  * qmgr_scan.c
514  */
515 extern QMGR_SCAN *qmgr_scan_create(const char *);
516 extern void qmgr_scan_request(QMGR_SCAN *, int);
517 extern char *qmgr_scan_next(QMGR_SCAN *);
518 
519  /*
520  * qmgr_error.c
521  */
522 extern QMGR_TRANSPORT *qmgr_error_transport(const char *);
523 extern QMGR_QUEUE *qmgr_error_queue(const char *, DSN *);
524 extern char *qmgr_error_nexthop(DSN *);
525 
526 /* LICENSE
527 /* .ad
528 /* .fi
529 /* The Secure Mailer license must be distributed with this software.
530 /* AUTHOR(S)
531 /* Wietse Venema
532 /* IBM T.J. Watson Research
533 /* P.O. Box 704
534 /* Yorktown Heights, NY 10598, USA
535 /*
536 /* Wietse Venema
537 /* Google, Inc.
538 /* 111 8th Avenue
539 /* New York, NY 10011, USA
540 /*
541 /* Preemptive scheduler enhancements:
542 /* Patrik Rak
543 /* Modra 6
544 /* 155 00, Prague, Czech Republic
545 /*--*/
struct HTABLE * job_byname
Definition: qmgr.h:190
int qmgr_active_feed(QMGR_SCAN *, const char *)
Definition: qmgr_active.c:171
double success
Definition: qmgr.h:205
QMGR_TRANSPORT * next
Definition: qmgr.h:98
int blocker_tag
Definition: qmgr.h:419
QMGR_QUEUE * qmgr_error_queue(const char *, DSN *)
Definition: qmgr_error.c:85
QMGR_JOB_LIST job_bytime
Definition: qmgr.h:193
void qmgr_message_free(QMGR_MESSAGE *)
QMGR_PEER * qmgr_peer_find(QMGR_JOB *, QMGR_QUEUE *)
Definition: qmgr_peer.c:115
int dest_concurrency_limit
Definition: qmgr.h:156
QMGR_ENTRY * next
Definition: qmgr.h:193
void qmgr_peer_free(QMGR_PEER *)
Definition: qmgr_peer.c:94
QMGR_ENTRY_LIST busy
Definition: qmgr.h:210
void qmgr_job_free(QMGR_JOB *)
Definition: qmgr_job.c:412
int stack_level
Definition: qmgr.h:417
QMGR_JOB * job_current
Definition: qmgr.h:194
int pending
Definition: qmgr.h:154
int rcpt_unused
Definition: qmgr.h:178
time_t last_done
Definition: qmgr.h:199
char * queue_id
Definition: qmgr.h:298
QMGR_ENTRY * qmgr_job_entry_select(QMGR_TRANSPORT *)
Definition: qmgr_job.c:829
int smtputf8
Definition: qmgr.h:303
int fail_cohort_limit
Definition: qmgr.h:165
void qmgr_message_kill_record(QMGR_MESSAGE *, long)
Definition: qmgr_message.c:868
char * client_addr
Definition: qmgr.h:312
QMGR_JOB_LIST message_peers
Definition: qmgr.h:411
QMGR_QUEUE * queue
Definition: qmgr.h:266
int selected_entries
Definition: qmgr.h:426
char * client_helo
Definition: qmgr.h:315
QMGR_PEER_LIST peers
Definition: qmgr.h:439
long data_size
Definition: qmgr.h:308
int slot_cost
Definition: qmgr.h:182
QMGR_TRANSPORT * qmgr_transport_create(const char *)
struct timeval active_time
Definition: qmgr.h:293
int blocker_tag
Definition: qmgr.h:253
char * sasl_sender
Definition: qmgr.h:318
QMGR_ENTRY * prev
Definition: qmgr.h:194
QMGR_JOB * stack_parent
Definition: qmgr.h:414
QMGR_TRANSPORT * qmgr_error_transport(const char *)
Definition: qmgr_error.c:65
int slots_available
Definition: qmgr.h:424
char * redirect_addr
Definition: qmgr.h:307
void qmgr_queue_suspend(QMGR_QUEUE *, int)
Definition: qmgr_queue.c:160
QMGR_FEEDBACK neg_feedback
Definition: qmgr.h:164
int read_entries
Definition: qmgr.h:428
double fail_cohorts
Definition: qmgr.h:207
void qmgr_entry_move_todo(QMGR_QUEUE *, QMGR_ENTRY *)
Definition: qmgr_entry.c:180
struct HTABLE * peer_byname
Definition: qmgr.h:420
QMGR_QUEUE * qmgr_queue_create(QMGR_TRANSPORT *, const char *, const char *)
Definition: qmgr_queue.c:407
QMGR_JOB * prev
Definition: qmgr.h:166
void qmgr_bounce_recipient(QMGR_MESSAGE *, RECIPIENT *, DSN *)
Definition: qmgr_bounce.c:57
char * log_ident
Definition: qmgr.h:319
int xport_rate_delay
Definition: qmgr.h:166
Definition: htable.h:25
time_t refill_time
Definition: qmgr.h:337
QMGR_JOB_LIST job_list
Definition: qmgr.h:191
int init_dest_concurrency
Definition: qmgr.h:157
char * client_port
Definition: qmgr.h:313
QMGR_QUEUE * next
Definition: qmgr.h:148
void qmgr_message_update_warn(QMGR_MESSAGE *)
Definition: qmgr_message.c:850
QMGR_SCAN * qmgr_scan_create(const char *)
Definition: qmgr_scan.c:176
long cont_length
Definition: qmgr.h:309
long warn_offset
Definition: qmgr.h:294
int rflags
Definition: qmgr.h:287
int slot_loan
Definition: qmgr.h:184
int rcpt_per_stack
Definition: qmgr.h:176
void qmgr_queue_unthrottle(QMGR_QUEUE *)
Definition: qmgr_queue.c:198
QMGR_JOB_LIST job_list
Definition: qmgr.h:370
long tflags_offset
Definition: qmgr.h:286
int flags
Definition: qmgr.h:283
int busy_refcount
Definition: qmgr.h:203
QMGR_QUEUE_LIST peers
Definition: qmgr.h:211
QMGR_MESSAGE * qmgr_message_alloc(const char *, const char *, int, mode_t)
struct timeval arrival_time
Definition: qmgr.h:291
struct HTABLE * queue_byname
Definition: qmgr.h:159
char * queue_name
Definition: qmgr.h:297
QMGR_JOB * qmgr_job_obtain(QMGR_MESSAGE *, QMGR_TRANSPORT *)
Definition: qmgr_job.c:246
QMGR_PEER * qmgr_peer_select(QMGR_JOB *)
Definition: qmgr_peer.c:133
QMGR_TRANSPORT * qmgr_transport_find(const char *)
QMGR_MESSAGE * qmgr_message_realloc(QMGR_MESSAGE *)
int flags
Definition: qmgr.h:153
void qmgr_active_drain(void)
Definition: qmgr_active.c:574
char * name
Definition: qmgr.h:200
QMGR_JOB_LIST stack_siblings
Definition: qmgr.h:416
void qmgr_scan_request(QMGR_SCAN *, int)
Definition: qmgr_scan.c:112
QMGR_PEER * qmgr_peer_obtain(QMGR_JOB *, QMGR_QUEUE *)
Definition: qmgr_peer.c:122
char * rewrite_context
Definition: qmgr.h:320
int refcount
Definition: qmgr.h:436
QMGR_ENTRY_LIST todo
Definition: qmgr.h:209
int rcpt_count
Definition: qmgr.h:429
QMGR_QUEUE * qmgr_queue_find(QMGR_TRANSPORT *, const char *)
Definition: qmgr_queue.c:439
QMGR_JOB_LIST stack_children
Definition: qmgr.h:415
QMGR_ENTRY * qmgr_entry_create(QMGR_QUEUE *, QMGR_MESSAGE *)
Definition: qmgr_entry.c:304
void qmgr_enable_queue(QMGR_QUEUE *)
Definition: qmgr_enable.c:98
char * sender
Definition: qmgr.h:300
void qmgr_queue_done(QMGR_QUEUE *)
Definition: qmgr_queue.c:374
void qmgr_job_blocker_update(QMGR_QUEUE *)
Definition: qmgr_job.c:950
void qmgr_queue_throttle(QMGR_QUEUE *, DSN *)
Definition: qmgr_queue.c:278
int qmgr_vrfy_pend_count
Definition: qmgr_message.c:152
int recipient_limit
Definition: qmgr.h:158
int dflags
Definition: qmgr.h:198
void qmgr_active_done(QMGR_MESSAGE *)
Definition: qmgr_active.c:258
QMGR_TRANSPORT * prev
Definition: qmgr.h:99
time_t warn_time
Definition: qmgr.h:295
void qmgr_entry_unselect(QMGR_QUEUE *, QMGR_ENTRY *)
Definition: qmgr_entry.c:170
long rcpt_offset
Definition: qmgr.h:310
QMGR_QUEUE * prev
Definition: qmgr.h:149
QMGR_TRANSPORT_LIST peers
Definition: qmgr.h:161
QMGR_ENTRY * qmgr_entry_select(QMGR_QUEUE *)
Definition: qmgr_entry.c:102
QMGR_JOB * job_next_unread
Definition: qmgr.h:195
void qmgr_defer_transport(QMGR_TRANSPORT *, DSN *)
Definition: qmgr_defer.c:83
void qmgr_entry_done(QMGR_ENTRY *, int)
Definition: qmgr_entry.c:212
int qmgr_deliver_concurrency
Definition: qmgr_deliver.c:93
time_t clog_time_to_warn
Definition: qmgr.h:213
QMGR_TRANSPORT * transport
Definition: qmgr.h:410
QMGR_JOB * candidate_cache
Definition: qmgr.h:196
char * name
Definition: qmgr.h:155
int rcpt_count
Definition: qmgr.h:367
RECIPIENT_LIST rcpt_list
Definition: qmgr.h:321
void qmgr_deliver(QMGR_TRANSPORT *, VSTREAM *)
Definition: qmgr_deliver.c:374
time_t candidate_cache_time
Definition: qmgr.h:199
int qflags
Definition: qmgr.h:284
char * dsn_envid
Definition: qmgr.h:301
char * sasl_username
Definition: qmgr.h:317
int rcpt_limit
Definition: qmgr.h:430
Definition: qmgr.h:408
void qmgr_transport_throttle(QMGR_TRANSPORT *, DSN *)
QMGR_PEER * qmgr_peer_create(QMGR_JOB *, QMGR_QUEUE *)
Definition: qmgr_peer.c:78
QMGR_MESSAGE * message
Definition: qmgr.h:264
void qmgr_enable_all(void)
Definition: qmgr_enable.c:60
int flags
Definition: qmgr.h:388
QMGR_ENTRY_LIST queue_peers
Definition: qmgr.h:307
void qmgr_defer_recipient(QMGR_MESSAGE *, RECIPIENT *, DSN *)
Definition: qmgr_defer.c:147
int todo_refcount
Definition: qmgr.h:202
QMGR_TRANSPORT * transport
Definition: qmgr.h:208
void qmgr_transport_unthrottle(QMGR_TRANSPORT *)
void qmgr_enable_transport(QMGR_TRANSPORT *)
Definition: qmgr_enable.c:77
void qmgr_defer_todo(QMGR_QUEUE *, DSN *)
Definition: qmgr_defer.c:103
double base
Definition: qmgr.h:115
int slots_used
Definition: qmgr.h:423
char * queue
Definition: qmgr.h:387
int hysteresis
Definition: qmgr.h:114
DSN * dsn
Definition: qmgr.h:162
void qmgr_transport_alloc(QMGR_TRANSPORT *, QMGR_TRANSPORT_ALLOC_NOTIFY)
int index
Definition: qmgr.h:116
QMGR_ENTRY_LIST peer_peers
Definition: qmgr.h:308
char * sasl_method
Definition: qmgr.h:316
QMGR_QUEUE_LIST queue_list
Definition: qmgr.h:160
void qmgr_feedback_init(QMGR_FEEDBACK *, const char *, const char *, const char *, const char *)
QMGR_TRANSPORT * qmgr_transport_select(void)
int qmgr_recipient_count
Definition: qmgr_message.c:151
QMGR_QUEUE * queue
Definition: qmgr.h:435
char * client_proto
Definition: qmgr.h:314
int qmgr_queue_count
Definition: qmgr_queue.c:112
QMGR_JOB * job
Definition: qmgr.h:434
long data_offset
Definition: qmgr.h:296
QMGR_PEER * prev
Definition: qmgr.h:405
int rcpt_limit
Definition: qmgr.h:368
Definition: dsn.h:17
struct SCAN_DIR * handle
Definition: qmgr.h:390
time_t create_time
Definition: qmgr.h:292
char * filter_xport
Definition: qmgr.h:305
QMGR_PEER_LIST peer_list
Definition: qmgr.h:422
char * client_name
Definition: qmgr.h:311
int single_rcpt
Definition: qmgr.h:290
char * qmgr_error_nexthop(DSN *)
Definition: qmgr_error.c:115
char * inspect_xport
Definition: qmgr.h:306
QMGR_PEER * peer
Definition: qmgr.h:306
int refill_delay
Definition: qmgr.h:181
QMGR_JOB_LIST time_peers
Definition: qmgr.h:413
time_t queued_time
Definition: qmgr.h:335
VSTREAM * fp
Definition: qmgr.h:288
VSTREAM * stream
Definition: qmgr.h:263
RECIPIENT_LIST rcpt_list
Definition: qmgr.h:265
QMGR_JOB * candidate_cache_current
Definition: qmgr.h:198
int tflags
Definition: qmgr.h:285
void qmgr_move(const char *, const char *, time_t)
Definition: qmgr_move.c:57
int slot_loan_factor
Definition: qmgr.h:185
QMGR_JOB * next
Definition: qmgr.h:165
int window
Definition: qmgr.h:204
int rate_delay
Definition: qmgr.h:167
QMGR_MESSAGE * message
Definition: qmgr.h:409
QMGR_FEEDBACK pos_feedback
Definition: qmgr.h:163
char * nexthop
Definition: qmgr.h:201
char * verp_delims
Definition: qmgr.h:304
QMGR_TRANSPORT_LIST qmgr_transport_list
struct HTABLE * qmgr_transport_byname
QMGR_ENTRY_LIST entry_list
Definition: qmgr.h:437
char * qmgr_scan_next(QMGR_SCAN *)
Definition: qmgr_scan.c:154
int blocker_tag
Definition: qmgr.h:201
int rcpt_unread
Definition: qmgr.h:369
int qmgr_message_count
Definition: qmgr_message.c:150
void qmgr_job_move_limits(QMGR_JOB *)
Definition: qmgr_job.c:278
DSN * dsn
Definition: qmgr.h:212
void(* QMGR_TRANSPORT_ALLOC_NOTIFY)(QMGR_TRANSPORT *, VSTREAM *)
Definition: qmgr.h:173
double failure
Definition: qmgr.h:206
int dsn_ret
Definition: qmgr.h:302
QMGR_PEER * next
Definition: qmgr.h:404
int min_slots
Definition: qmgr.h:186
int refill_limit
Definition: qmgr.h:179
int refcount
Definition: qmgr.h:289
QMGR_JOB_LIST transport_peers
Definition: qmgr.h:412
char * encoding
Definition: qmgr.h:299
int nflags
Definition: qmgr.h:389