]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - usr.sbin/rpc.ypxfrd/ypxfrd_main.c
Optionally bind ktls threads to NUMA domains
[FreeBSD/FreeBSD.git] / usr.sbin / rpc.ypxfrd / ypxfrd_main.c
1 /*-
2  * SPDX-License-Identifier: BSD-4-Clause
3  *
4  * Copyright (c) 1995, 1996
5  *      Bill Paul <wpaul@ctr.columbia.edu>.  All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. All advertising materials mentioning features or use of this software
16  *    must display the following acknowledgement:
17  *      This product includes software developed by Bill Paul.
18  * 4. Neither the name of the author nor the names of any co-contributors
19  *    may be used to endorse or promote products derived from this software
20  *    without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR CONTRIBUTORS BE LIABLE
26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  */
34
35 #include <sys/cdefs.h>
36 __FBSDID("$FreeBSD$");
37
38 #include "ypxfrd.h"
39 #include <err.h>
40 #include <fcntl.h>
41 #include <paths.h>
42 #include <stdio.h>
43 #include <stdlib.h> /* getenv, exit */
44 #include <unistd.h>
45 #include <rpc/pmap_clnt.h> /* for pmap_unset */
46 #include <rpc/rpc_com.h>
47 #include <string.h> /* strcmp */
48 #include <signal.h>
49 #include <sys/ttycom.h> /* TIOCNOTTY */
50 #ifdef __cplusplus
51 #include <sysent.h> /* getdtablesize, open */
52 #endif /* __cplusplus */
53 #include <memory.h>
54 #include <sys/socket.h>
55 #include <netinet/in.h>
56 #include <syslog.h>
57 #include "ypxfrd_extern.h"
58 #include <sys/wait.h>
59 #include <errno.h>
60
61 #ifndef SIG_PF
62 #define SIG_PF void(*)(int)
63 #endif
64
65 #ifdef DEBUG
66 #define RPC_SVC_FG
67 #endif
68
69 #define _RPCSVC_CLOSEDOWN 120
70 int _rpcpmstart;                /* Started by a port monitor ? */
71 static int _rpcfdtype;
72                  /* Whether Stream or Datagram ? */
73         /* States a server can be in wrt request */
74
75 #define _IDLE 0
76 #define _SERVED 1
77 #define _SERVING 2
78
79 extern int _rpcsvcstate;         /* Set when a request is serviced */
80
81 int debug;
82
83 char *progname = "rpc.ypxfrd";
84 char *yp_dir = "/var/yp/";
85
86 static void
87 _msgout(char *msg)
88 {
89 #ifdef RPC_SVC_FG
90         if (_rpcpmstart)
91                 syslog(LOG_ERR, "%s", msg);
92         else
93                 warnx("%s", msg);
94 #else
95         syslog(LOG_ERR, "%s", msg);
96 #endif
97 }
98
99 static void
100 closedown(int sig)
101 {
102         if (_rpcsvcstate == _IDLE) {
103                 extern fd_set svc_fdset;
104                 static int size;
105                 int i, openfd;
106
107                 if (_rpcfdtype == SOCK_DGRAM)
108                         exit(0);
109                 if (size == 0) {
110                         size = getdtablesize();
111                 }
112                 for (i = 0, openfd = 0; i < size && openfd < 2; i++)
113                         if (FD_ISSET(i, &svc_fdset))
114                                 openfd++;
115                 if (openfd <= 1)
116                         exit(0);
117         }
118         if (_rpcsvcstate == _SERVED)
119                 _rpcsvcstate = _IDLE;
120
121         (void) signal(SIGALRM, (SIG_PF) closedown);
122         (void) alarm(_RPCSVC_CLOSEDOWN/2);
123 }
124
125
126 static void
127 ypxfrd_svc_run(void)
128 {
129 #ifdef FD_SETSIZE
130         fd_set readfds;
131 #else
132         int readfds;
133 #endif /* def FD_SETSIZE */
134         extern int forked;
135         int pid;
136         int fd_setsize = _rpc_dtablesize();
137
138         /* Establish the identity of the parent ypserv process. */
139         pid = getpid();
140
141         for (;;) {
142 #ifdef FD_SETSIZE
143                 readfds = svc_fdset;
144 #else
145                 readfds = svc_fds;
146 #endif /* def FD_SETSIZE */
147                 switch (select(fd_setsize, &readfds, NULL, NULL,
148                                (struct timeval *)0)) {
149                 case -1:
150                         if (errno == EINTR) {
151                                 continue;
152                         }
153                         warn("svc_run: - select failed");
154                         return;
155                 case 0:
156                         continue;
157                 default:
158                         svc_getreqset(&readfds);
159                         if (forked && pid != getpid())
160                                 exit(0);
161                 }
162         }
163 }
164
165 static void reaper(int sig)
166 {
167         int                     status;
168         int                     saved_errno;
169
170         saved_errno = errno;
171
172         if (sig == SIGHUP) {
173                 load_securenets();
174                 errno = saved_errno;
175                 return;
176         }
177
178         if (sig == SIGCHLD) {
179                 while (wait3(&status, WNOHANG, NULL) > 0)
180                         children--;
181         } else {
182                 (void) pmap_unset(YPXFRD_FREEBSD_PROG, YPXFRD_FREEBSD_VERS);
183                 exit(0);
184         }
185
186         errno = saved_errno;
187         return;
188 }
189
190 void
191 usage(void)
192 {
193         fprintf(stderr, "usage: rpc.ypxfrd [-p path]\n");
194         exit(0);
195 }
196
197 int
198 main(int argc, char *argv[])
199 {
200         register SVCXPRT *transp = NULL;
201         int sock;
202         int proto = 0;
203         struct sockaddr_in saddr;
204         int asize = sizeof (saddr);
205         int ch;
206
207         while ((ch = getopt(argc, argv, "p:h")) != -1) {
208                 switch (ch) {
209                 case 'p':
210                         yp_dir = optarg;
211                         break;
212                 default:
213                         usage();
214                         break;
215                 }
216         }
217
218         load_securenets();
219
220         if (getsockname(0, (struct sockaddr *)&saddr, &asize) == 0) {
221                 int ssize = sizeof (int);
222
223                 if (saddr.sin_family != AF_INET)
224                         exit(1);
225                 if (getsockopt(0, SOL_SOCKET, SO_TYPE,
226                                 (char *)&_rpcfdtype, &ssize) == -1)
227                         exit(1);
228                 sock = 0;
229                 _rpcpmstart = 1;
230                 proto = 0;
231                 openlog("rpc.ypxfrd", LOG_PID, LOG_DAEMON);
232         } else {
233 #ifndef RPC_SVC_FG
234                 int size;
235                 int pid, i;
236
237                 pid = fork();
238                 if (pid < 0)
239                         err(1, "fork");
240                 if (pid)
241                         exit(0);
242                 size = getdtablesize();
243                 for (i = 0; i < size; i++)
244                         (void) close(i);
245                 i = open(_PATH_CONSOLE, 2);
246                 (void) dup2(i, 1);
247                 (void) dup2(i, 2);
248                 i = open(_PATH_TTY, 2);
249                 if (i >= 0) {
250                         (void) ioctl(i, TIOCNOTTY, (char *)NULL);
251                         (void) close(i);
252                 }
253                 openlog("rpc.ypxfrd", LOG_PID, LOG_DAEMON);
254 #endif
255                 sock = RPC_ANYSOCK;
256                 (void) pmap_unset(YPXFRD_FREEBSD_PROG, YPXFRD_FREEBSD_VERS);
257         }
258
259         if ((_rpcfdtype == 0) || (_rpcfdtype == SOCK_DGRAM)) {
260                 transp = svcudp_create(sock);
261                 if (transp == NULL) {
262                         _msgout("cannot create udp service.");
263                         exit(1);
264                 }
265                 if (!_rpcpmstart)
266                         proto = IPPROTO_UDP;
267                 if (!svc_register(transp, YPXFRD_FREEBSD_PROG, YPXFRD_FREEBSD_VERS, ypxfrd_freebsd_prog_1, proto)) {
268                         _msgout("unable to register (YPXFRD_FREEBSD_PROG, YPXFRD_FREEBSD_VERS, udp).");
269                         exit(1);
270                 }
271         }
272
273         if ((_rpcfdtype == 0) || (_rpcfdtype == SOCK_STREAM)) {
274                 transp = svctcp_create(sock, 0, 0);
275                 if (transp == NULL) {
276                         _msgout("cannot create tcp service.");
277                         exit(1);
278                 }
279                 if (!_rpcpmstart)
280                         proto = IPPROTO_TCP;
281                 if (!svc_register(transp, YPXFRD_FREEBSD_PROG, YPXFRD_FREEBSD_VERS, ypxfrd_freebsd_prog_1, proto)) {
282                         _msgout("unable to register (YPXFRD_FREEBSD_PROG, YPXFRD_FREEBSD_VERS, tcp).");
283                         exit(1);
284                 }
285         }
286
287         if (transp == (SVCXPRT *)NULL) {
288                 _msgout("could not create a handle");
289                 exit(1);
290         }
291         if (_rpcpmstart) {
292                 (void) signal(SIGALRM, (SIG_PF) closedown);
293                 (void) alarm(_RPCSVC_CLOSEDOWN/2);
294         }
295
296         (void) signal(SIGPIPE, SIG_IGN);
297         (void) signal(SIGCHLD, (SIG_PF) reaper);
298         (void) signal(SIGTERM, (SIG_PF) reaper);
299         (void) signal(SIGINT, (SIG_PF) reaper);
300         (void) signal(SIGHUP, (SIG_PF) reaper);
301
302         ypxfrd_svc_run();
303         _msgout("svc_run returned");
304         exit(1);
305         /* NOTREACHED */
306 }