1 #ifndef OPT_SERV_H 2 #define OPT_SERV_H 3 4 #include "opt.h" 5 #include "conf.h" 6 #include "evnt.h" 7 8 #define OPT_SERV_CONF_BUF_SZ (128 - sizeof(Vstr_node_buf)) 9 #define OPT_SERV_CONF_MEM_PREALLOC_MAX (128 * 1024) 10 11 #define OPT_SERV_CONF_USE_DAEMON FALSE 12 #define OPT_SERV_CONF_USE_DROP_PRIVS FALSE 13 #define OPT_SERV_CONF_USE_PDEATHSIG FALSE 14 #define OPT_SERV_CONF_DEF_RLIM_CORE_CALL FALSE 15 #define OPT_SERV_CONF_DEF_RLIM_FILE_CALL FALSE 16 #define OPT_SERV_CONF_DEF_TCP_DEFER_ACCEPT 8 /* HC usage txt */ 17 #define OPT_SERV_CONF_DEF_PRIV_UID 60001 18 #define OPT_SERV_CONF_DEF_PRIV_GID 60001 19 #define OPT_SERV_CONF_DEF_NUM_PROCS 1 20 #define OPT_SERV_CONF_DEF_IDLE_TIMEOUT (2 * 60) 21 #define OPT_SERV_CONF_DEF_Q_LISTEN_LEN 128 22 #define OPT_SERV_CONF_DEF_MAX_CONNECTIONS 0 23 #define OPT_SERV_CONF_DEF_RLIM_CORE_NUM 0 24 #define OPT_SERV_CONF_DEF_RLIM_FILE_NUM 0 25 26 typedef struct Opt_serv_policy_opts 27 { 28 Vstr_ref *ref; 29 struct Opt_serv_policy_opts *next; 30 struct Opt_serv_opts *beg; 31 32 Vstr_base *policy_name; 33 34 unsigned int idle_timeout; 35 unsigned int max_connections; 36 } Opt_serv_policy_opts; 37 38 typedef struct Opt_serv_addr_opts 39 { 40 struct Opt_serv_addr_opts *next; 41 Vstr_base *acpt_filter_file; 42 Vstr_base *ipv4_address; 43 unsigned short tcp_port; 44 unsigned int defer_accept; 45 unsigned int q_listen_len; 46 unsigned int max_connections; 47 } Opt_serv_addr_opts; 48 49 typedef struct Opt_serv_opts 50 { 51 Opt_serv_policy_opts *def_policy; 52 53 Opt_serv_policy_opts *(*make_policy)(struct Opt_serv_opts *); 54 int (*copy_policy)(struct Opt_serv_policy_opts *, 55 const struct Opt_serv_policy_opts *); 56 57 const char *vers_cstr; 58 const size_t vers_len; 59 60 const char *name_cstr; 61 size_t name_len; 62 63 unsigned int become_daemon : 1; 64 unsigned int drop_privs : 1; 65 unsigned int use_pdeathsig : 1; 66 unsigned int no_conf_listen : 1; 67 unsigned int rlim_core_call : 1; 68 unsigned int rlim_file_call : 1; 69 70 Vstr_base *pid_file; 71 Vstr_base *cntl_file; 72 Vstr_base *chroot_dir; 73 74 Vstr_base *vpriv_uid; 75 uid_t priv_uid; 76 Vstr_base *vpriv_gid; 77 gid_t priv_gid; 78 unsigned int num_procs; 79 80 unsigned int rlim_core_num; 81 unsigned int rlim_file_num; 82 83 unsigned int max_spare_bases; 84 85 unsigned int max_spare_buf_nodes; 86 unsigned int max_spare_ptr_nodes; 87 unsigned int max_spare_ref_nodes; 88 89 Opt_serv_addr_opts *addr_beg; 90 } Opt_serv_opts; 91 92 /* uid/gid default to NFS nobody */ 93 #define OPT_SERV_CONF_INIT_OPTS(x, y) \ 94 NULL, \ 95 opt_policy_make, \ 96 opt_policy_copy, \ 97 x, \ 98 sizeof(x) - 1, \ 99 y, \ 100 sizeof(y) - 1, \ 101 OPT_SERV_CONF_USE_DAEMON, \ 102 OPT_SERV_CONF_USE_DROP_PRIVS, \ 103 OPT_SERV_CONF_USE_PDEATHSIG, \ 104 FALSE, \ 105 OPT_SERV_CONF_DEF_RLIM_CORE_CALL, \ 106 OPT_SERV_CONF_DEF_RLIM_FILE_CALL, \ 107 NULL, NULL, NULL, \ 108 NULL, OPT_SERV_CONF_DEF_PRIV_UID, \ 109 NULL, OPT_SERV_CONF_DEF_PRIV_GID, \ 110 OPT_SERV_CONF_DEF_NUM_PROCS, \ 111 OPT_SERV_CONF_DEF_RLIM_CORE_NUM, \ 112 OPT_SERV_CONF_DEF_RLIM_FILE_NUM, \ 113 4, \ 114 (OPT_SERV_CONF_MEM_PREALLOC_MAX / OPT_SERV_CONF_BUF_SZ), \ 115 (OPT_SERV_CONF_MEM_PREALLOC_MAX / OPT_SERV_CONF_BUF_SZ), \ 116 (OPT_SERV_CONF_MEM_PREALLOC_MAX / OPT_SERV_CONF_BUF_SZ), \ 117 NULL 118 119 #define OPT_SERV_CONF_DECL_OPTS(N, x, y) \ 120 Opt_serv_opts N[1] = {{OPT_SERV_CONF_INIT_OPTS(x, y)}} 121 122 extern void opt_serv_conf_free(Opt_serv_opts *); 123 extern int opt_serv_conf_init(Opt_serv_opts *); 124 125 extern Opt_serv_addr_opts *opt_serv_make_addr(Opt_serv_opts *); 126 127 extern int opt_serv_conf(Opt_serv_opts *, Conf_parse *, Conf_token *); 128 extern int opt_serv_conf_parse_cstr(Vstr_base *, Opt_serv_opts *, const char *); 129 extern int opt_serv_conf_parse_file(Vstr_base *, Opt_serv_opts *, const char *); 130 131 extern void opt_serv_logger(Vlg *); 132 133 extern int opt_serv_sc_tst(Conf_parse *, Conf_token *, int *, 134 int (*tst_func)(Conf_parse *, Conf_token *, 135 int *, void *), void *); 136 137 extern int opt_serv_match_init(struct Opt_serv_opts *, 138 Conf_parse *, Conf_token *, int *); 139 140 extern void opt_serv_sc_drop_privs(Opt_serv_opts *); 141 extern void opt_serv_sc_rlim_file_num(unsigned int); 142 extern void opt_serv_sc_rlim_core_num(unsigned int); 143 extern int opt_serv_sc_acpt_end(const Opt_serv_policy_opts *, 144 struct Evnt *, struct Evnt *); 145 extern void opt_serv_sc_free_beg(struct Evnt *, struct Vstr_ref *); 146 extern void opt_serv_sc_signals(void); 147 extern void opt_serv_sc_check_children(void); 148 extern void opt_serv_sc_cntl_resources(const Opt_serv_opts *); 149 extern int opt_serv_sc_append_hostname(Vstr_base *, size_t); 150 extern int opt_serv_sc_append_cwd(Vstr_base *, size_t); 151 extern int opt_serv_sc_make_static_path(struct Opt_serv_opts *, 152 Conf_parse *, Conf_token *, 153 Vstr_base *); 154 155 156 #define OPT_SERV_DECL_GETOPTS() \ 157 {"help", no_argument, NULL, 'h'}, \ 158 {"daemon", optional_argument, NULL, 1}, \ 159 {"chroot", required_argument, NULL, 2}, \ 160 {"drop-privs", optional_argument, NULL, 3}, \ 161 {"priv-uid", required_argument, NULL, 4}, \ 162 {"priv-gid", required_argument, NULL, 5}, \ 163 {"pid-file", required_argument, NULL, 6}, \ 164 {"cntl-file", required_argument, NULL, 7}, \ 165 {"acpt-filter-file", required_argument, NULL, 8}, \ 166 {"accept-filter-file", required_argument, NULL, 8}, \ 167 {"processes", required_argument, NULL, 9}, \ 168 {"procs", required_argument, NULL, 9}, \ 169 {"debug", no_argument, NULL, 'd'}, \ 170 {"host", required_argument, NULL, 'H'}, \ 171 {"port", required_argument, NULL, 'P'}, \ 172 {"nagle", optional_argument, NULL, 'n'}, \ 173 {"max-connections", required_argument, NULL, 'M'}, \ 174 {"idle-timeout", required_argument, NULL, 't'}, \ 175 {"defer-accept", required_argument, NULL, 10}, \ 176 {"version", no_argument, NULL, 'V'} 177 178 #define OPT_SERV_GETOPTS(opts) \ 179 case 't': opts->def_policy->idle_timeout = atoi(optarg); break; \ 180 case 'H': OPT_VSTR_ARG(opts->addr_beg->ipv4_address); break; \ 181 case 'M': OPT_NUM_NR_ARG(opts->addr_beg->max_connections, \ 182 "max connections"); \ 183 opts->def_policy->max_connections = opts->addr_beg->max_connections; \ 184 break; \ 185 case 'P': OPT_NUM_ARG(opts->addr_beg->tcp_port, "tcp port", \ 186 0, 65535, ""); \ 187 opts->no_conf_listen = FALSE; break; \ 188 case 'd': vlg_debug(vlg); break; \ 189 \ 190 case 'n': OPT_TOGGLE_ARG(evnt_opt_nagle); break; \ 191 \ 192 case 1: OPT_TOGGLE_ARG(opts->become_daemon); break; \ 193 case 2: OPT_VSTR_ARG(opts->chroot_dir); break; \ 194 case 3: OPT_TOGGLE_ARG(opts->drop_privs); break; \ 195 case 4: OPT_VSTR_ARG(opts->vpriv_uid); break; \ 196 case 5: OPT_VSTR_ARG(opts->vpriv_gid); break; \ 197 case 6: OPT_VSTR_ARG(opts->pid_file); break; \ 198 case 7: OPT_VSTR_ARG(opts->cntl_file); break; \ 199 case 8: OPT_VSTR_ARG(opts->addr_beg->acpt_filter_file); break; \ 200 case 9: OPT_NUM_ARG(opts->num_procs, "number of processes", \ 201 1, 255, ""); break; \ 202 case 10: OPT_NUM_ARG(opts->addr_beg->defer_accept, \ 203 "seconds to defer connections", \ 204 0, 4906, " (1 hour 8 minutes)"); break 205 206 207 208 /* simple typer for EQ */ 209 #define OPT_SERV_SYM_EQ(x) \ 210 conf_token_cmp_sym_cstr_eq(conf, token, x) 211 212 /* eXport data from configuration file to structs... */ 213 #define OPT_SERV_X_TOGGLE(x) do { \ 214 int opt__val = (x); \ 215 \ 216 if (conf_sc_token_parse_toggle(conf, token, &opt__val)) \ 217 return (FALSE); \ 218 (x) = opt__val; \ 219 } while (FALSE) 220 221 #define OPT_SERV_X_UINT(x) do { \ 222 unsigned int opt__val = 0; \ 223 \ 224 if (conf_sc_token_parse_uint(conf, token, &opt__val)) \ 225 return (FALSE); \ 226 (x) = opt__val; \ 227 } while (FALSE) 228 229 #define OPT_SERV_X__ESC_VSTR(x, p, l) do { \ 230 if ((token->type == CONF_TOKEN_TYPE_QUOTE_ESC_D) || \ 231 (token->type == CONF_TOKEN_TYPE_QUOTE_ESC_DDD) || \ 232 (token->type == CONF_TOKEN_TYPE_QUOTE_ESC_S) || \ 233 (token->type == CONF_TOKEN_TYPE_QUOTE_ESC_SSS) || \ 234 FALSE) \ 235 if (!conf_sc_conv_unesc((x), p, l, NULL)) \ 236 return (FALSE); \ 237 } while (FALSE) 238 239 #define OPT_SERV_X__VSTR(x, p, l) do { \ 240 if (conf_sc_token_sub_vstr(conf, token, x, p, l)) \ 241 return (FALSE); \ 242 \ 243 if ((x)->conf->malloc_bad) \ 244 return (FALSE); \ 245 OPT_SERV_X__ESC_VSTR(x, p, token->u.node->len); \ 246 } while (FALSE) 247 248 #define OPT_SERV_X_VSTR(x) OPT_SERV_X__VSTR(x, 1, (x)->len) 249 250 #define OPT_SERV_SC_MATCH_INIT(x, y) do { \ 251 unsigned int match_init__depth = token->depth_num; \ 252 int match_init__matches = TRUE; \ 253 \ 254 if (!opt_serv_match_init(x, conf, token, &match_init__matches)) \ 255 return (FALSE); \ 256 \ 257 if (!match_init__matches) \ 258 conf_parse_end_token(conf, token, match_init__depth); \ 259 \ 260 while (conf_token_list_num(token, match_init__depth)) \ 261 { \ 262 CONF_SC_PARSE_DEPTH_TOKEN_RET(conf, token, match_init__depth, FALSE); \ 263 CONF_SC_TOGGLE_CLIST_VAR(clist); \ 264 if (!(y)) \ 265 return (FALSE); \ 266 } \ 267 } while (FALSE) 268 269 #endif 270