Lines Matching +full:mux +full:- +full:ctrl +full:- +full:specifier
1 /*-
2 * SPDX-License-Identifier: BSD-3-Clause
33 * Inetd - Internet super-server
35 * This program invokes all internet services as needed. Connection-oriented
46 * out. The first type of server is said to be ``multi-threaded'';
47 * the second type of server ``single-threaded''.
60 * wait/nowait single-threaded/multi-threaded
61 * user[:group][/login-class] user/group/login-class to run daemon as
66 * RFC1078-based tcpmux internal service. Tcpmux listens on port 1 for
77 * because they do not have a well-known port and hence cannot listen
84 * wait/nowait single-threaded/multi-threaded
85 * user[:group][/login-class] user/group/login-class to run daemon as
157 ( ((wrap_ex && !(sep)->se_bi) || (wrap_bi && (sep)->se_bi)) \
158 && (sep->se_family == AF_INET || sep->se_family == AF_INET6) \
159 && ( ((sep)->se_accept && (sep)->se_socktype == SOCK_STREAM) \
160 || (sep)->se_socktype == SOCK_DGRAM))
171 #define MAXCHILD -1 /* maximum number of this service
176 #define MAXCPM -1 /* rate limit invocations from a
182 #define MAXPERIP -1 /* maximum number of this service
223 static struct conninfo *search_conn(struct servtab *sep, int ctrl);
248 static int maxsock; /* highest-numbered descriptor */
304 sa = (struct sockaddr *)req->client->sin; in whichaf()
308 if (sa->sa_family == AF_INET6 && in whichaf()
309 IN6_IS_ADDR_V4MAPPED(&satosin6(sa)->sin6_addr)) in whichaf()
312 return sa->sa_family; in whichaf()
343 while ((ch = getopt(argc, argv, "dlwWR:a:c:C:p:s:")) != -1) in main()
354 "-R %s: bad value for service invocation rate"); in main()
358 "-c %s: bad value for maximum children"); in main()
362 "-C %s: bad value for maximum children/minute"); in main()
372 "-s %s: bad value for maximum children per source address"); in main()
383 "usage: inetd [-dlWw] [-a address] [-C rate]" in main()
384 " [-c maximum] [-p filename] [-R rate]" in main()
385 " [-s maximum] [configuration_file]"); in main()
406 syslog(LOG_ERR, "-a %s: %s", hostname, gai_strerror(error)); in main()
412 if (res->ai_addr == NULL) { in main()
413 syslog(LOG_ERR, "-a %s: getaddrinfo failed", hostname); in main()
416 switch (res->ai_addr->sa_family) { in main()
420 bind_sa4 = satosin(res->ai_addr); in main()
422 bind_sa4->sin_port = 0; in main()
429 bind_sa6 = satosin6(res->ai_addr); in main()
431 bind_sa6->sin6_port = 0; in main()
442 } while ((res = res->ai_next) != NULL); in main()
448 syslog(LOG_ERR, "-a %s: unknown address family", hostname); in main()
456 argc -= optind; in main()
491 if (pfh != NULL && pidfile_write(pfh) == -1) { in main()
541 (void)memset(dummy, 'x', DUMMYSIZE - 1); in main()
542 dummy[DUMMYSIZE - 1] = '\0'; in main()
557 int n, ctrl; in main() local
584 while (--nsig >= 0) { in main()
607 for (sep = servtab; n && sep; sep = sep->se_next) in main()
608 if (sep->se_fd != -1 && FD_ISSET(sep->se_fd, &readable)) { in main()
609 n--; in main()
611 warnx("someone wants %s", sep->se_service); in main()
612 dofork = !sep->se_bi || sep->se_bi->bi_fork || ISWRAP(sep); in main()
614 if (sep->se_accept && sep->se_socktype == SOCK_STREAM) { in main()
616 if (ioctl(sep->se_fd, FIONBIO, &i) < 0) in main()
618 ctrl = accept(sep->se_fd, (struct sockaddr *)0, in main()
621 warnx("accept, ctrl %d", ctrl); in main()
622 if (ctrl < 0) { in main()
626 sep->se_service); in main()
627 if (sep->se_accept && in main()
628 sep->se_socktype == SOCK_STREAM) in main()
629 close(ctrl); in main()
633 if (ioctl(sep->se_fd, FIONBIO, &i) < 0) in main()
635 if (ioctl(ctrl, FIONBIO, &i) < 0) in main()
637 if (cpmip(sep, ctrl) < 0) { in main()
638 close(ctrl); in main()
642 (conn = search_conn(sep, ctrl)) != NULL && in main()
644 close(ctrl); in main()
648 ctrl = sep->se_fd; in main()
653 if (getpeername(ctrl, (struct sockaddr *) in main()
656 if (recvfrom(ctrl, buf, sizeof(buf), in main()
671 syslog(LOG_INFO,"%s from %s", sep->se_service, pname); in main()
681 if (sep->se_count++ == 0) in main()
682 (void)clock_gettime(CLOCK_MONOTONIC_FAST, &sep->se_time); in main()
683 else if (toomany > 0 && sep->se_count >= toomany) { in main()
687 if (now.tv_sec - sep->se_time.tv_sec > in main()
689 sep->se_time = now; in main()
690 sep->se_count = 1; in main()
694 sep->se_service, sep->se_proto); in main()
695 if (sep->se_accept && in main()
696 sep->se_socktype == SOCK_STREAM) in main()
697 close(ctrl); in main()
712 if (sep->se_accept && in main()
713 sep->se_socktype == SOCK_STREAM) in main()
714 close(ctrl); in main()
736 if (sep->se_bi && in main()
737 sep->se_bi->bi_fn == (bi_fn_t *) tcpmux) { in main()
738 sep = tcpmux(ctrl); in main()
740 close(ctrl); in main()
746 inetd_setproctitle("wrapping", ctrl); in main()
747 service = sep->se_server_name ? in main()
748 sep->se_server_name : sep->se_service; in main()
749 request_init(&req, RQ_DAEMON, service, RQ_FILE, ctrl, 0); in main()
757 eval_client(&req), service, sep->se_proto, in main()
759 if (sep->se_socktype != SOCK_STREAM) in main()
760 recv(ctrl, buf, sizeof (buf), 0); in main()
769 eval_client(&req), service, sep->se_proto, in main()
774 if (sep->se_bi) { in main()
775 (*sep->se_bi->bi_fn)(ctrl, sep); in main()
779 getpid(), sep->se_server); in main()
780 /* Clear close-on-exec. */ in main()
781 if (fcntl(ctrl, F_SETFD, 0) < 0) { in main()
784 sep->se_service, sep->se_proto); in main()
787 if (ctrl != 0) { in main()
788 dup2(ctrl, 0); in main()
789 close(ctrl); in main()
793 if ((pwd = getpwnam(sep->se_user)) == NULL) { in main()
796 sep->se_service, sep->se_proto, in main()
797 sep->se_user); in main()
798 if (sep->se_socktype != SOCK_STREAM) in main()
803 if ( sep->se_group != NULL in main()
804 && (grp = getgrnam(sep->se_group)) == NULL in main()
808 sep->se_service, sep->se_proto, in main()
809 sep->se_group); in main()
810 if (sep->se_socktype != SOCK_STREAM) in main()
815 pwd->pw_gid = grp->gr_gid; in main()
817 if ((lc = login_getclass(sep->se_class)) == NULL) { in main()
821 sep->se_service, sep->se_proto, in main()
822 sep->se_class); in main()
823 if (sep->se_socktype != SOCK_STREAM) in main()
831 sep->se_service); in main()
835 if (setusercontext(lc, pwd, pwd->pw_uid, in main()
840 sep->se_service, sep->se_user); in main()
845 if (pwd->pw_uid) { in main()
846 if (setlogin(sep->se_user) < 0) { in main()
849 sep->se_service, sep->se_user); in main()
852 if (setgid(pwd->pw_gid) < 0) { in main()
855 sep->se_service, pwd->pw_gid); in main()
858 (void) initgroups(pwd->pw_name, in main()
859 pwd->pw_gid); in main()
860 if (setuid(pwd->pw_uid) < 0) { in main()
863 sep->se_service, pwd->pw_uid); in main()
870 execv(sep->se_server, sep->se_argv); in main()
872 "cannot execute %s: %m", sep->se_server); in main()
873 if (sep->se_socktype != SOCK_STREAM) in main()
879 if (sep->se_accept && sep->se_socktype == SOCK_STREAM) in main()
880 close(ctrl); in main()
914 __func__, sep->se_numchild, sep->se_maxchild); in addchild()
923 sc->sc_pid = pid; in addchild()
924 LIST_INSERT_HEAD(&sep->se_children, sc, sc_link); in addchild()
925 ++sep->se_numchild; in addchild()
947 for (sep = servtab; sep; sep = sep->se_next) { in reapchild()
948 LIST_FOREACH(sc, &sep->se_children, sc_link) { in reapchild()
949 if (sc->sc_pid == pid) in reapchild()
958 --sep->se_numchild; in reapchild()
962 sep->se_server, pid, in reapchild()
986 for (sep = servtab; sep; sep = sep->se_next) in config()
987 sep->se_checked = 0; in config()
989 if (getpwnam(new->se_user) == NULL) { in config()
992 new->se_service, new->se_proto, new->se_user); in config()
995 if (new->se_group && getgrnam(new->se_group) == NULL) { in config()
998 new->se_service, new->se_proto, new->se_group); in config()
1002 if ((lc = login_getclass(new->se_class)) == NULL) { in config()
1006 new->se_service, new->se_proto, new->se_class); in config()
1011 new_nomapped = new->se_nomapped; in config()
1012 for (sep = servtab; sep; sep = sep->se_next) in config()
1013 if (strcmp(sep->se_service, new->se_service) == 0 && in config()
1014 strcmp(sep->se_proto, new->se_proto) == 0 && in config()
1015 sep->se_rpc == new->se_rpc && in config()
1016 sep->se_socktype == new->se_socktype && in config()
1017 sep->se_family == new->se_family) in config()
1024 if (sep->se_nomapped != new->se_nomapped) { in config()
1026 if (!sep->se_rpc) in config()
1027 sep->se_nomapped = new->se_nomapped; in config()
1028 sep->se_reset = 1; in config()
1036 sep->se_maxcpm = new->se_maxcpm; in config()
1037 sep->se_maxchild = new->se_maxchild; in config()
1038 resize_conn(sep, new->se_maxperip); in config()
1039 sep->se_maxperip = new->se_maxperip; in config()
1040 sep->se_bi = new->se_bi; in config()
1042 if (sep->se_fd >= 0) { in config()
1044 if (FD_ISSET(sep->se_fd, &allsock)) in config()
1047 if (!FD_ISSET(sep->se_fd, &allsock)) in config()
1051 sep->se_accept = new->se_accept; in config()
1052 SWAP(char *, sep->se_user, new->se_user); in config()
1053 SWAP(char *, sep->se_group, new->se_group); in config()
1055 SWAP(char *, sep->se_class, new->se_class); in config()
1057 SWAP(char *, sep->se_server, new->se_server); in config()
1058 SWAP(char *, sep->se_server_name, new->se_server_name); in config()
1060 SWAP(char *, sep->se_argv[i], new->se_argv[i]); in config()
1062 SWAP(char *, sep->se_policy, new->se_policy); in config()
1074 sep->se_checked = 1; in config()
1076 sep->se_fd = -1; in config()
1079 switch (sep->se_family) { in config()
1082 sep->se_fd = -1; in config()
1089 sep->se_fd = -1; in config()
1095 if (!sep->se_rpc) { in config()
1096 if (sep->se_family != AF_UNIX) { in config()
1097 sp = getservbyname(sep->se_service, sep->se_proto); in config()
1100 sep->se_service, sep->se_proto); in config()
1101 sep->se_checked = 0; in config()
1105 switch (sep->se_family) { in config()
1107 if (sp->s_port != sep->se_ctrladdr4.sin_port) { in config()
1108 sep->se_ctrladdr4.sin_port = in config()
1109 sp->s_port; in config()
1110 sep->se_reset = 1; in config()
1115 if (sp->s_port != in config()
1116 sep->se_ctrladdr6.sin6_port) { in config()
1117 sep->se_ctrladdr6.sin6_port = in config()
1118 sp->s_port; in config()
1119 sep->se_reset = 1; in config()
1124 if (sep->se_reset != 0 && sep->se_fd >= 0) in config()
1127 rpc = getrpcbyname(sep->se_service); in config()
1130 sep->se_service, sep->se_proto); in config()
1131 if (sep->se_fd != -1) in config()
1132 (void) close(sep->se_fd); in config()
1133 sep->se_fd = -1; in config()
1136 if (sep->se_reset != 0 || in config()
1137 rpc->r_number != sep->se_rpc_prog) { in config()
1138 if (sep->se_rpc_prog) in config()
1140 sep->se_rpc_prog = rpc->r_number; in config()
1141 if (sep->se_fd != -1) in config()
1142 (void) close(sep->se_fd); in config()
1143 sep->se_fd = -1; in config()
1145 sep->se_nomapped = new_nomapped; in config()
1147 sep->se_reset = 0; in config()
1148 if (sep->se_fd == -1) in config()
1158 if (sep->se_checked) { in config()
1159 sepp = &sep->se_next; in config()
1162 *sepp = sep->se_next; in config()
1163 if (sep->se_fd >= 0) in config()
1167 if (sep->se_rpc && sep->se_rpc_prog > 0) in config()
1184 netid4 = sep->se_socktype == SOCK_DGRAM ? udpconf : tcpconf; in unregisterrpc()
1185 netid6 = sep->se_socktype == SOCK_DGRAM ? udp6conf : tcp6conf; in unregisterrpc()
1186 if (sep->se_family == AF_INET) in unregisterrpc()
1188 else if (sep->se_nomapped) in unregisterrpc()
1191 * Conflict if same prog and protocol - In that case one should look in unregisterrpc()
1198 for (sepp = servtab; sepp; sepp = sepp->se_next) { in unregisterrpc()
1201 if (sepp->se_checked == 0 || in unregisterrpc()
1202 !sepp->se_rpc || in unregisterrpc()
1203 strcmp(sep->se_proto, sepp->se_proto) != 0 || in unregisterrpc()
1204 sep->se_rpc_prog != sepp->se_rpc_prog) in unregisterrpc()
1206 if (sepp->se_family == AF_INET) in unregisterrpc()
1208 if (sepp->se_family == AF_INET6) { in unregisterrpc()
1210 if (!sep->se_nomapped) in unregisterrpc()
1218 for (i = sep->se_rpc_lowvers; i <= sep->se_rpc_highvers; i++) { in unregisterrpc()
1220 rpcb_unset(sep->se_rpc_prog, i, netid4); in unregisterrpc()
1222 rpcb_unset(sep->se_rpc_prog, i, netid6); in unregisterrpc()
1224 if (sep->se_fd != -1) in unregisterrpc()
1225 (void) close(sep->se_fd); in unregisterrpc()
1226 sep->se_fd = -1; in unregisterrpc()
1236 for (sep = servtab; sep; sep = sep->se_next) in retry()
1237 if (sep->se_fd == -1 && !ISMUX(sep)) in retry()
1246 /* Set all listening sockets to close-on-exec. */ in setup()
1247 if ((sep->se_fd = socket(sep->se_family, in setup()
1248 sep->se_socktype | SOCK_CLOEXEC, 0)) < 0) { in setup()
1251 sep->se_service, sep->se_proto); in setup()
1253 sep->se_service, sep->se_proto); in setup()
1258 if (strcmp(sep->se_proto, "tcp") == 0 && (options & SO_DEBUG) && in setup()
1259 turnon(sep->se_fd, SO_DEBUG) < 0) in setup()
1261 if (turnon(sep->se_fd, SO_REUSEADDR) < 0) in setup()
1264 if (turnon(sep->se_fd, SO_PRIVSTATE) < 0) in setup()
1269 if ((sep->se_family == AF_INET6) && in setup()
1270 (strcmp(sep->se_proto, "udp") == 0) && in setup()
1271 (sep->se_accept == 0) && in setup()
1272 (setsockopt(sep->se_fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, in setup()
1275 if (sep->se_family == AF_INET6) { in setup()
1276 int flag = sep->se_nomapped ? 1 : 0; in setup()
1277 if (setsockopt(sep->se_fd, IPPROTO_IPV6, IPV6_V6ONLY, in setup()
1286 if (sep->se_family == AF_UNIX) { in setup()
1287 (void) unlink(sep->se_ctrladdr_un.sun_path); in setup()
1290 if (bind(sep->se_fd, (struct sockaddr *)&sep->se_ctrladdr, in setup()
1291 sep->se_ctrladdr_size) < 0) { in setup()
1294 sep->se_service, sep->se_proto); in setup()
1296 sep->se_service, sep->se_proto); in setup()
1297 (void) close(sep->se_fd); in setup()
1298 sep->se_fd = -1; in setup()
1303 if (sep->se_family == AF_UNIX) in setup()
1307 if (sep->se_family == AF_UNIX) { in setup()
1308 /* Ick - fch{own,mod} don't work on Unix domain sockets */ in setup()
1309 if (chown(sep->se_service, sep->se_sockuid, sep->se_sockgid) < 0) in setup()
1311 if (chmod(sep->se_service, sep->se_sockmode) < 0) in setup()
1315 if (sep->se_rpc) { in setup()
1317 socklen_t len = sep->se_ctrladdr_size; in setup()
1324 if (getsockname(sep->se_fd, in setup()
1325 (struct sockaddr*)&sep->se_ctrladdr, &len) < 0){ in setup()
1327 sep->se_service, sep->se_proto); in setup()
1328 (void) close(sep->se_fd); in setup()
1329 sep->se_fd = -1; in setup()
1332 nbuf.buf = &sep->se_ctrladdr; in setup()
1333 nbuf.len = sep->se_ctrladdr.sa_len; in setup()
1334 if (sep->se_family == AF_INET) in setup()
1335 netid = sep->se_socktype==SOCK_DGRAM? udpconf:tcpconf; in setup()
1338 netid = sep->se_socktype==SOCK_DGRAM? udp6conf:tcp6conf; in setup()
1339 if (!sep->se_nomapped) { /* INET and INET6 */ in setup()
1345 sock.sin_port = sep->se_ctrladdr6.sin6_port; in setup()
1352 sep->se_service, sep->se_proto); in setup()
1353 (void) close(sep->se_fd); in setup()
1354 sep->se_fd = -1; in setup()
1360 for (i = sep->se_rpc_lowvers; i <= sep->se_rpc_highvers; i++) { in setup()
1361 rpcb_unset(sep->se_rpc_prog, i, netid); in setup()
1362 rpcb_set(sep->se_rpc_prog, i, netid, &nbuf); in setup()
1364 rpcb_unset(sep->se_rpc_prog, i, netid2); in setup()
1365 rpcb_set(sep->se_rpc_prog, i, netid2, &nbuf2); in setup()
1369 if (sep->se_socktype == SOCK_STREAM) in setup()
1370 listen(sep->se_fd, -1); in setup()
1374 sep->se_server, sep->se_fd); in setup()
1388 switch (sep->se_family) { in ipsecsetup()
1403 if (!sep->se_policy || sep->se_policy[0] == '\0') { in ipsecsetup()
1408 if (!strncmp("in", sep->se_policy, 2)) in ipsecsetup()
1409 policy_in = sep->se_policy; in ipsecsetup()
1410 else if (!strncmp("out", sep->se_policy, 3)) in ipsecsetup()
1411 policy_out = sep->se_policy; in ipsecsetup()
1414 sep->se_policy); in ipsecsetup()
1422 if (setsockopt(sep->se_fd, level, opt, in ipsecsetup()
1426 sep->se_service, sep->se_proto, in ipsecsetup()
1436 if (setsockopt(sep->se_fd, level, opt, in ipsecsetup()
1440 sep->se_service, sep->se_proto, in ipsecsetup()
1456 if (sep->se_fd >= 0) { in close_sep()
1457 if (FD_ISSET(sep->se_fd, &allsock)) in close_sep()
1459 (void) close(sep->se_fd); in close_sep()
1460 sep->se_fd = -1; in close_sep()
1462 sep->se_count = 0; in close_sep()
1463 sep->se_numchild = 0; /* forget about any existing children */ in close_sep()
1481 if (strcmp(name2, se->s_name) == 0) in matchservent()
1483 for (alias = se->s_aliases; *alias; alias++) in matchservent()
1502 sep->se_fd = -1; in enter()
1504 sep->se_next = servtab; in enter()
1515 "enabling %s, fd %d", sep->se_service, sep->se_fd); in enable()
1517 if (sep->se_fd < 0) { in enable()
1519 "%s: %s: bad fd", __func__, sep->se_service); in enable()
1524 "%s: %s: is mux", __func__, sep->se_service); in enable()
1527 if (FD_ISSET(sep->se_fd, &allsock)) { in enable()
1529 "%s: %s: not off", __func__, sep->se_service); in enable()
1534 FD_SET(sep->se_fd, &allsock); in enable()
1535 maxsock = MAX(maxsock, sep->se_fd); in enable()
1543 "disabling %s, fd %d", sep->se_service, sep->se_fd); in disable()
1545 if (sep->se_fd < 0) { in disable()
1547 "%s: %s: bad fd", __func__, sep->se_service); in disable()
1552 "%s: %s: is mux", __func__, sep->se_service); in disable()
1555 if (!FD_ISSET(sep->se_fd, &allsock)) { in disable()
1557 "%s: %s: not on", __func__, sep->se_service); in disable()
1564 nsock--; in disable()
1566 FD_CLR(sep->se_fd, &allsock); in disable()
1567 if (sep->se_fd == maxsock) in disable()
1568 maxsock--; in disable()
1604 #define MUX_LEN (sizeof(TCPMUX_TOKEN)-1) in getconfigent()
1683 sep->se_sockuid = pw->pw_uid; in getconfigent()
1688 sep->se_sockgid = gr->gr_gid; in getconfigent()
1689 sep->se_sockmode = strtol(perm, &arg, 8); in getconfigent()
1696 sep->se_sockuid = euid; in getconfigent()
1697 sep->se_sockgid = egid; in getconfigent()
1698 sep->se_sockmode = 0200; in getconfigent()
1703 sep->se_type = MUXPLUS_TYPE; in getconfigent()
1706 sep->se_type = MUX_TYPE; in getconfigent()
1707 sep->se_service = newstr(c); in getconfigent()
1709 sep->se_service = newstr(arg); in getconfigent()
1710 sep->se_type = NORM_TYPE; in getconfigent()
1714 sep->se_socktype = SOCK_STREAM; in getconfigent()
1716 sep->se_socktype = SOCK_DGRAM; in getconfigent()
1718 sep->se_socktype = SOCK_RDM; in getconfigent()
1720 sep->se_socktype = SOCK_SEQPACKET; in getconfigent()
1722 sep->se_socktype = SOCK_RAW; in getconfigent()
1724 sep->se_socktype = -1; in getconfigent()
1728 sep->se_proto = newstr(strsep(&arg, "/")); in getconfigent()
1734 if (sep->se_type == NORM_TYPE && in getconfigent()
1739 sep->se_proto = newstr(arg); in getconfigent()
1741 if (strncmp(sep->se_proto, "rpc/", 4) == 0) { in getconfigent()
1742 memmove(sep->se_proto, sep->se_proto + 4, in getconfigent()
1743 strlen(sep->se_proto) + 1 - 4); in getconfigent()
1744 sep->se_rpc = 1; in getconfigent()
1745 sep->se_rpc_prog = sep->se_rpc_lowvers = in getconfigent()
1746 sep->se_rpc_highvers = 0; in getconfigent()
1747 if ((versp = strrchr(sep->se_service, '/'))) { in getconfigent()
1749 switch (sscanf(versp, "%u-%u", in getconfigent()
1750 &sep->se_rpc_lowvers, in getconfigent()
1751 &sep->se_rpc_highvers)) { in getconfigent()
1755 sep->se_rpc_highvers = in getconfigent()
1756 sep->se_rpc_lowvers; in getconfigent()
1760 "bad RPC version specifier; %s", in getconfigent()
1761 sep->se_service); in getconfigent()
1767 sep->se_rpc_lowvers = in getconfigent()
1768 sep->se_rpc_highvers = 1; in getconfigent()
1771 sep->se_nomapped = 0; in getconfigent()
1772 if (strcmp(sep->se_proto, "unix") == 0) { in getconfigent()
1773 sep->se_family = AF_UNIX; in getconfigent()
1775 while (isdigit(sep->se_proto[strlen(sep->se_proto) - 1])) { in getconfigent()
1777 if (sep->se_proto[strlen(sep->se_proto) - 1] == '6') { in getconfigent()
1778 sep->se_proto[strlen(sep->se_proto) - 1] = '\0'; in getconfigent()
1783 if (sep->se_proto[strlen(sep->se_proto) - 1] == '4') { in getconfigent()
1784 sep->se_proto[strlen(sep->se_proto) - 1] = '\0'; in getconfigent()
1791 syslog(LOG_ERR, "bad IP version for %s", sep->se_proto); in getconfigent()
1798 sep->se_service); in getconfigent()
1807 sep->se_family = AF_INET6; in getconfigent()
1809 sep->se_nomapped = 1; in getconfigent()
1815 sep->se_service); in getconfigent()
1819 sep->se_family = AF_INET; in getconfigent()
1823 switch(sep->se_family) { in getconfigent()
1825 memcpy(&sep->se_ctrladdr4, bind_sa4, in getconfigent()
1826 sizeof(sep->se_ctrladdr4)); in getconfigent()
1827 sep->se_ctrladdr_size = sizeof(sep->se_ctrladdr4); in getconfigent()
1831 memcpy(&sep->se_ctrladdr6, bind_sa6, in getconfigent()
1832 sizeof(sep->se_ctrladdr6)); in getconfigent()
1833 sep->se_ctrladdr_size = sizeof(sep->se_ctrladdr6); in getconfigent()
1837 #define SUN_PATH_MAXSIZE sizeof(sep->se_ctrladdr_un.sun_path) in getconfigent()
1838 memset(&sep->se_ctrladdr, 0, sizeof(sep->se_ctrladdr)); in getconfigent()
1839 sep->se_ctrladdr_un.sun_family = sep->se_family; in getconfigent()
1840 if (strlcpy(sep->se_ctrladdr_un.sun_path, sep->se_service, in getconfigent()
1844 sep->se_service); in getconfigent()
1848 sep->se_ctrladdr_size = sep->se_ctrladdr_un.sun_len = in getconfigent()
1849 SUN_LEN(&sep->se_ctrladdr_un); in getconfigent()
1853 sep->se_accept = 0; in getconfigent()
1855 sep->se_accept = 1; in getconfigent()
1859 CONFIG, sep->se_service); in getconfigent()
1862 sep->se_maxchild = -1; in getconfigent()
1863 sep->se_maxcpm = -1; in getconfigent()
1864 sep->se_maxperip = -1; in getconfigent()
1872 "%s: bad max-child for service %s", in getconfigent()
1873 CONFIG, sep->se_service); in getconfigent()
1877 if (!sep->se_accept && val != 1) in getconfigent()
1879 " not recommended", val, sep->se_service); in getconfigent()
1880 sep->se_maxchild = val; in getconfigent()
1882 sep->se_maxcpm = strtol(eptr + 1, &eptr, 10); in getconfigent()
1884 sep->se_maxperip = strtol(eptr + 1, &eptr, 10); in getconfigent()
1895 sep->se_accept = 1; in getconfigent()
1896 if (strcmp(sep->se_proto, "tcp")) { in getconfigent()
1899 CONFIG, sep->se_service); in getconfigent()
1902 if (sep->se_socktype != SOCK_STREAM) { in getconfigent()
1905 CONFIG, sep->se_service); in getconfigent()
1909 sep->se_user = newstr(sskip(&cp)); in getconfigent()
1911 if ((s = strrchr(sep->se_user, '/')) != NULL) { in getconfigent()
1913 sep->se_class = newstr(s + 1); in getconfigent()
1915 sep->se_class = newstr(RESOURCE_RC); in getconfigent()
1917 if ((s = strrchr(sep->se_user, ':')) != NULL) { in getconfigent()
1919 sep->se_group = newstr(s + 1); in getconfigent()
1921 sep->se_group = NULL; in getconfigent()
1922 sep->se_server = newstr(sskip(&cp)); in getconfigent()
1923 if ((sep->se_server_name = strrchr(sep->se_server, '/'))) in getconfigent()
1924 sep->se_server_name++; in getconfigent()
1925 if (strcmp(sep->se_server, "internal") == 0) { in getconfigent()
1928 for (bi = biltins; bi->bi_service; bi++) in getconfigent()
1929 if (bi->bi_socktype == sep->se_socktype && in getconfigent()
1930 matchservent(bi->bi_service, sep->se_service, in getconfigent()
1931 sep->se_proto)) in getconfigent()
1933 if (bi->bi_service == 0) { in getconfigent()
1935 sep->se_service); in getconfigent()
1938 sep->se_accept = 1; /* force accept mode for built-ins */ in getconfigent()
1939 sep->se_bi = bi; in getconfigent()
1941 sep->se_bi = NULL; in getconfigent()
1942 if (sep->se_maxperip < 0) in getconfigent()
1943 sep->se_maxperip = maxperip; in getconfigent()
1944 if (sep->se_maxcpm < 0) in getconfigent()
1945 sep->se_maxcpm = maxcpm; in getconfigent()
1946 if (sep->se_maxchild < 0) { /* apply default max-children */ in getconfigent()
1947 if (sep->se_bi && sep->se_bi->bi_maxchild >= 0) in getconfigent()
1948 sep->se_maxchild = sep->se_bi->bi_maxchild; in getconfigent()
1949 else if (sep->se_accept) in getconfigent()
1950 sep->se_maxchild = MAX(maxchild, 0); in getconfigent()
1952 sep->se_maxchild = 1; in getconfigent()
1954 LIST_INIT(&sep->se_children); in getconfigent()
1958 sep->se_argv[argc++] = newstr(arg); in getconfigent()
1962 CONFIG, sep->se_service); in getconfigent()
1966 sep->se_argv[argc++] = NULL; in getconfigent()
1968 LIST_INIT(&sep->se_conn[i]); in getconfigent()
1970 sep->se_policy = policy ? newstr(policy) : NULL; in getconfigent()
1982 free(cp->se_service); in freeconfig()
1983 free(cp->se_proto); in freeconfig()
1984 free(cp->se_user); in freeconfig()
1985 free(cp->se_group); in freeconfig()
1987 free(cp->se_class); in freeconfig()
1989 free(cp->se_server); in freeconfig()
1990 while (!LIST_EMPTY(&cp->se_children)) { in freeconfig()
1991 sc = LIST_FIRST(&cp->se_children); in freeconfig()
1996 if (cp->se_argv[i]) in freeconfig()
1997 free(cp->se_argv[i]); in freeconfig()
2000 free(cp->se_policy); in freeconfig()
2006 * Safe skip - if skip returns null, log a syntax error in the
2105 for (se2 = servtab; se2; se2 = se2->se_next) { in check_loop()
2106 if (!se2->se_bi || se2->se_socktype != SOCK_DGRAM) in check_loop()
2109 switch (se2->se_family) { in check_loop()
2111 if (csatosin(sa)->sin_port == in check_loop()
2112 se2->se_ctrladdr4.sin_port) in check_loop()
2117 if (csatosin6(sa)->sin6_port == in check_loop()
2118 se2->se_ctrladdr6.sin6_port) in check_loop()
2126 getnameinfo(sa, sa->sa_len, pname, sizeof(pname), NULL, 0, in check_loop()
2129 sep->se_service, sep->se_proto, in check_loop()
2130 se2->se_service, se2->se_proto, in check_loop()
2154 action, sep->se_service, sep->se_proto, in print_service()
2155 sep->se_accept, sep->se_maxchild, sep->se_user, sep->se_group, in print_service()
2157 sep->se_class, in print_service()
2159 (void *) sep->se_bi, sep->se_server in print_service()
2161 , (sep->se_policy ? sep->se_policy : "") in print_service()
2167 #define CPMHMASK (CPMHSIZE-1)
2192 cpmip(const struct servtab *sep, int ctrl) in cpmip() argument
2203 if (sep->se_maxcpm > 0 && in cpmip()
2204 (sep->se_family == AF_INET || sep->se_family == AF_INET6) && in cpmip()
2205 getpeername(ctrl, (struct sockaddr *)&rss, &rssLen) == 0 ) { in cpmip()
2227 p = (char *)&sin4->sin_addr; in cpmip()
2232 p = (char *)&sin6->sin6_addr; in cpmip()
2238 return -1; in cpmip()
2250 ch->ch_Family == AF_INET && in cpmip()
2251 sin4->sin_addr.s_addr == ch->ch_Addr4.s_addr && in cpmip()
2252 ch->ch_Service && strcmp(sep->se_service, in cpmip()
2253 ch->ch_Service) == 0) { in cpmip()
2259 ch->ch_Family == AF_INET6 && in cpmip()
2260 IN6_ARE_ADDR_EQUAL(&sin6->sin6_addr, in cpmip()
2261 &ch->ch_Addr6) != 0 && in cpmip()
2262 ch->ch_Service && strcmp(sep->se_service, in cpmip()
2263 ch->ch_Service) == 0) { in cpmip()
2268 if (chBest == NULL || ch->ch_LTime == 0 || in cpmip()
2269 ch->ch_LTime < chBest->ch_LTime) { in cpmip()
2274 (chBest->ch_Family != AF_INET || in cpmip()
2275 sin4->sin_addr.s_addr != chBest->ch_Addr4.s_addr)) || in cpmip()
2276 chBest->ch_Service == NULL || in cpmip()
2277 strcmp(sep->se_service, chBest->ch_Service) != 0) { in cpmip()
2278 chBest->ch_Family = sin4->sin_family; in cpmip()
2279 chBest->ch_Addr4 = sin4->sin_addr; in cpmip()
2280 free(chBest->ch_Service); in cpmip()
2281 chBest->ch_Service = strdup(sep->se_service); in cpmip()
2282 memset(chBest->ch_Times, 0, sizeof(chBest->ch_Times)); in cpmip()
2286 (chBest->ch_Family != AF_INET6 || in cpmip()
2287 IN6_ARE_ADDR_EQUAL(&sin6->sin6_addr, in cpmip()
2288 &chBest->ch_Addr6) == 0)) || in cpmip()
2289 chBest->ch_Service == NULL || in cpmip()
2290 strcmp(sep->se_service, chBest->ch_Service) != 0) { in cpmip()
2291 chBest->ch_Family = sin6->sin6_family; in cpmip()
2292 chBest->ch_Addr6 = sin6->sin6_addr; in cpmip()
2293 free(chBest->ch_Service); in cpmip()
2294 chBest->ch_Service = strdup(sep->se_service); in cpmip()
2295 memset(chBest->ch_Times, 0, sizeof(chBest->ch_Times)); in cpmip()
2298 chBest->ch_LTime = t; in cpmip()
2300 CTime *ct = &chBest->ch_Times[ticks % CHTSIZE]; in cpmip()
2301 if (ct->ct_Ticks != ticks) { in cpmip()
2302 ct->ct_Ticks = ticks; in cpmip()
2303 ct->ct_Count = 0; in cpmip()
2305 ++ct->ct_Count; in cpmip()
2308 CTime *ct = &chBest->ch_Times[i]; in cpmip()
2309 if (ct->ct_Ticks <= ticks && in cpmip()
2310 ct->ct_Ticks >= ticks - CHTSIZE) { in cpmip()
2311 cnt += ct->ct_Count; in cpmip()
2314 if ((cnt * 60) / (CHTSIZE * CHTGRAN) > sep->se_maxcpm) { in cpmip()
2318 ((struct sockaddr *)&rss)->sa_len, in cpmip()
2321 r = -1; in cpmip()
2324 sep->se_service, pname, in cpmip()
2325 sep->se_maxcpm); in cpmip()
2332 search_conn(struct servtab *sep, int ctrl) in search_conn() argument
2340 if (sep->se_maxperip <= 0) in search_conn()
2347 if (getpeername(ctrl, (struct sockaddr *)&ss, &sslen) != 0) in search_conn()
2352 hv = hashval((char *)&((struct sockaddr_in *)&ss)->sin_addr, in search_conn()
2357 hv = hashval((char *)&((struct sockaddr_in6 *)&ss)->sin6_addr, in search_conn()
2373 LIST_FOREACH(conn, &sep->se_conn[hv], co_link) { in search_conn()
2374 if (getnameinfo((struct sockaddr *)&conn->co_addr, in search_conn()
2375 conn->co_addr.ss_len, pname2, sizeof(pname2), NULL, 0, in search_conn()
2386 conn->co_proc = reallocarray(NULL, sep->se_maxperip, in search_conn()
2387 sizeof(*conn->co_proc)); in search_conn()
2388 if (conn->co_proc == NULL) { in search_conn()
2392 memcpy(&conn->co_addr, (struct sockaddr *)&ss, sslen); in search_conn()
2393 conn->co_numchild = 0; in search_conn()
2394 LIST_INSERT_HEAD(&sep->se_conn[hv], conn, co_link); in search_conn()
2411 if (conn->co_numchild >= sep->se_maxperip) { in room_conn()
2412 getnameinfo((struct sockaddr *)&conn->co_addr, in room_conn()
2413 conn->co_addr.ss_len, pname, sizeof(pname), NULL, 0, in room_conn()
2416 sep->se_service, pname, sep->se_maxperip); in room_conn()
2431 if (proc->pr_conn != NULL) { in addchild_conn()
2436 proc->pr_conn = conn; in addchild_conn()
2439 conn->co_proc[conn->co_numchild++] = proc; in addchild_conn()
2451 if ((conn = proc->pr_conn) == NULL) in reapchild_conn()
2453 for (i = 0; i < conn->co_numchild; ++i) in reapchild_conn()
2454 if (conn->co_proc[i] == proc) { in reapchild_conn()
2455 conn->co_proc[i] = conn->co_proc[--conn->co_numchild]; in reapchild_conn()
2468 if (sep->se_maxperip <= 0) in resize_conn()
2475 LIST_FOREACH(conn, &sep->se_conn[i], co_link) { in resize_conn()
2476 for (j = maxpip; j < conn->co_numchild; ++j) in resize_conn()
2477 free_proc(conn->co_proc[j]); in resize_conn()
2478 conn->co_proc = reallocarray(conn->co_proc, maxpip, in resize_conn()
2479 sizeof(*conn->co_proc)); in resize_conn()
2480 if (conn->co_proc == NULL) { in resize_conn()
2484 if (conn->co_numchild > maxpip) in resize_conn()
2485 conn->co_numchild = maxpip; in resize_conn()
2497 LIST_FOREACH_SAFE(conn, &sep->se_conn[i], co_link, conn_temp) { in free_connlist()
2502 for (j = 0; j < conn->co_numchild; ++j) in free_connlist()
2503 free_proc(conn->co_proc[j]); in free_connlist()
2504 conn->co_numchild = 0; in free_connlist()
2515 if (conn->co_numchild <= 0) { in free_conn()
2517 free(conn->co_proc); in free_conn()
2530 if (proc->pr_pid == pid) in search_proc()
2538 proc->pr_pid = pid; in search_proc()
2539 proc->pr_conn = NULL; in search_proc()
2562 hv = (hv ^ (hv >> 16)) & (PERIPSIZE - 1); in hashval()