Postfix3.3.1
master_listen.c
[詳解]
1 /*++
2 /* NAME
3 /* master_listen 3
4 /* SUMMARY
5 /* Postfix master - start/stop listeners
6 /* SYNOPSIS
7 /* #include "master.h"
8 /*
9 /* void master_listen_init(serv)
10 /* MASTER_SERV *serv;
11 /*
12 /* void master_listen_cleanup(serv)
13 /* MASTER_SERV *serv;
14 /* DESCRIPTION
15 /* master_listen_init() turns on the listener implemented by the
16 /* named process. FIFOs and UNIX-domain sockets are created with
17 /* mode 0622 and with ownership mail_owner.
18 /*
19 /* master_listen_cleanup() turns off the listener implemented by the
20 /* named process.
21 /* DIAGNOSTICS
22 /* BUGS
23 /* SEE ALSO
24 /* inet_listen(3), internet-domain listener
25 /* unix_listen(3), unix-domain listener
26 /* fifo_listen(3), named-pipe listener
27 /* upass_listen(3), file descriptor passing listener
28 /* set_eugid(3), set effective user/group attributes
29 /* LICENSE
30 /* .ad
31 /* .fi
32 /* The Secure Mailer license must be distributed with this software.
33 /* AUTHOR(S)
34 /* Wietse Venema
35 /* IBM T.J. Watson Research
36 /* P.O. Box 704
37 /* Yorktown Heights, NY 10598, USA
38 /*--*/
39 
40 /* System library. */
41 
42 #include <sys_defs.h>
43 #include <sys/socket.h>
44 #include <netinet/in.h>
45 #include <arpa/inet.h>
46 #include <unistd.h>
47 #include <string.h>
48 
49 /* Utility library. */
50 
51 #include <msg.h>
52 #include <listen.h>
53 #include <mymalloc.h>
54 #include <stringops.h>
55 #include <inet_addr_list.h>
56 #include <set_eugid.h>
57 #include <set_ugid.h>
58 #include <iostuff.h>
59 #include <myaddrinfo.h>
60 #include <sock_addr.h>
61 
62 /* Global library. */
63 
64 #include <mail_params.h>
65 
66 /* Application-specific. */
67 
68 #include "master.h"
69 
70 /* master_listen_init - enable connection requests */
71 
73 {
74  const char *myname = "master_listen_init";
75  char *end_point;
76  int n;
77  MAI_HOSTADDR_STR hostaddr;
78  struct sockaddr *sa;
79 
80  /*
81  * Find out what transport we should use, then create one or more
82  * listener sockets. Make the listener sockets non-blocking, so that
83  * child processes don't block in accept() when multiple processes are
84  * selecting on the same socket and only one of them gets the connection.
85  */
86  switch (serv->type) {
87 
88  /*
89  * UNIX-domain or stream listener endpoints always come as singlets.
90  */
93  serv->listen_fd[0] =
94  LOCAL_LISTEN(serv->name, serv->max_proc > var_proc_limit ?
97  set_ugid(getuid(), getgid());
98  break;
99 
100  /*
101  * FIFO listener endpoints always come as singlets.
102  */
105  serv->listen_fd[0] = fifo_listen(serv->name, 0622, NON_BLOCKING);
107  set_ugid(getuid(), getgid());
108  break;
109 
110  /*
111  * INET-domain listener endpoints can be wildcarded (the default) or
112  * bound to specific interface addresses.
113  *
114  * With dual-stack IPv4/6 systems it does not matter, we have to specify
115  * the addresses anyway, either explicit or wild-card.
116  */
118  for (n = 0; n < serv->listen_fd_count; n++) {
119  sa = SOCK_ADDR_PTR(MASTER_INET_ADDRLIST(serv)->addrs + n);
120  SOCKADDR_TO_HOSTADDR(sa, SOCK_ADDR_LEN(sa), &hostaddr,
121  (MAI_SERVPORT_STR *) 0, 0);
122  end_point = concatenate(hostaddr.buf,
123  ":", MASTER_INET_PORT(serv), (char *) 0);
124  serv->listen_fd[n]
125  = inet_listen(end_point, serv->max_proc > var_proc_limit ?
126  serv->max_proc : var_proc_limit, NON_BLOCKING);
128  myfree(end_point);
129  }
130  break;
131 
132  /*
133  * Descriptor passing endpoints always come as singlets.
134  */
135 #ifdef MASTER_SERV_TYPE_PASS
138  serv->listen_fd[0] =
139  LOCAL_LISTEN(serv->name, serv->max_proc > var_proc_limit ?
140  serv->max_proc : var_proc_limit, NON_BLOCKING);
142  set_ugid(getuid(), getgid());
143  break;
144 #endif
145  default:
146  msg_panic("%s: unknown service type: %d", myname, serv->type);
147  }
148 }
149 
150 /* master_listen_cleanup - disable connection requests */
151 
153 {
154  const char *myname = "master_listen_cleanup";
155  int n;
156 
157  /*
158  * XXX The listen socket is shared with child processes. Closing the
159  * socket in the master process does not really disable listeners in
160  * child processes. There seems to be no documented way to turn off a
161  * listener. The 4.4BSD shutdown(2) man page promises an ENOTCONN error
162  * when shutdown(2) is applied to a socket that is not connected.
163  */
164  for (n = 0; n < serv->listen_fd_count; n++) {
165  if (close(serv->listen_fd[n]) < 0)
166  msg_warn("%s: close listener socket %d: %m",
167  myname, serv->listen_fd[n]);
168  serv->listen_fd[n] = -1;
169  }
170 }
void myfree(void *ptr)
Definition: mymalloc.c:207
#define LOCAL_LISTEN
Definition: sys_defs.h:1422
int listen_fd_count
Definition: master.h:35
int inet_listen(const char *addr, int backlog, int block_mode)
Definition: inet_listen.c:82
NORETURN msg_panic(const char *fmt,...)
Definition: msg.c:295
#define MASTER_SERV_TYPE_PASS
Definition: master.h:81
#define SOCKADDR_TO_HOSTADDR(sa, salen, host, port, sock)
Definition: myaddrinfo.h:197
#define MASTER_INET_ADDRLIST(s)
Definition: master.h:41
int var_proc_limit
Definition: mail_params.c:317
char * name
Definition: master.h:30
char buf[MAI_HOSTADDR_STRSIZE]
Definition: myaddrinfo.h:146
int type
Definition: master.h:31
gid_t var_owner_gid
Definition: mail_params.c:235
uid_t var_owner_uid
Definition: mail_params.c:234
void master_listen_init(MASTER_SERV *serv)
Definition: master_listen.c:72
#define SOCK_ADDR_PTR(ptr)
Definition: sock_addr.h:24
void msg_warn(const char *fmt,...)
Definition: msg.c:215
#define MASTER_SERV_TYPE_UNIX
Definition: master.h:78
void master_listen_cleanup(MASTER_SERV *serv)
int fifo_listen(const char *path, int permissions, int block_mode)
Definition: fifo_listen.c:52
#define MASTER_SERV_TYPE_INET
Definition: master.h:79
void set_eugid(uid_t euid, gid_t egid)
Definition: set_eugid.c:54
char * concatenate(const char *arg0,...)
Definition: concatenate.c:42
int max_proc
Definition: master.h:44
#define NON_BLOCKING
Definition: iostuff.h:49
void set_ugid(uid_t uid, gid_t gid)
Definition: set_ugid.c:45
#define SOCK_ADDR_LEN(sa)
Definition: sock_addr.h:78
#define MASTER_INET_PORT(s)
Definition: master.h:42
#define CLOSE_ON_EXEC
Definition: iostuff.h:51
int * listen_fd
Definition: master.h:34
#define MASTER_SERV_TYPE_FIFO
Definition: master.h:80
int close_on_exec(int fd, int on)
Definition: close_on_exec.c:49