📄 portcfg.c
字号:
/* Return here if NULL pointer given. */ if (port == NULL) return; /* Delete from port configuration hash if necessary. */ if (svz_portcfgs && (name = svz_hash_contains (svz_portcfgs, port)) != NULL) svz_hash_delete (svz_portcfgs, name); /* Free the name of the port configuration. */ svz_free (port->name); /* Depending on the type of configuration perform various operations. */ switch (port->proto) { case PROTO_TCP: svz_free (port->tcp_ipaddr); break; case PROTO_UDP: svz_free (port->udp_ipaddr); break; case PROTO_ICMP: svz_free (port->icmp_ipaddr); break; case PROTO_RAW: svz_free (port->raw_ipaddr); break; case PROTO_PIPE: svz_free (port->pipe_recv.user); svz_free (port->pipe_recv.name); svz_free (port->pipe_recv.group); svz_free (port->pipe_send.user); svz_free (port->pipe_send.name); svz_free (port->pipe_send.group); break; } /* Destroy access and connection list. */ svz_portcfg_destroy_access (port); svz_portcfg_destroy_accepted (port); /* Free the port configuration itself. */ svz_free (port);}/* * Destroy the deny and allowed access list of the given port configuration * @var{port}. */voidsvz_portcfg_destroy_access (svz_portcfg_t *port){ char *ip; int n; if (port->deny) { svz_array_foreach (port->deny, ip, n) svz_free (ip); svz_array_destroy (port->deny); port->deny = NULL; } if (port->allow) { svz_array_foreach (port->allow, ip, n) svz_free (ip); svz_array_destroy (port->allow); port->allow = NULL; } }/* * Destroy the list of connections for each ip address ever connected to the * given port configuration @var{port}. */voidsvz_portcfg_destroy_accepted (svz_portcfg_t *port){ int n; char **ip; if (port->accepted) { svz_hash_foreach_key (port->accepted, ip, n) svz_vector_destroy (svz_hash_get (port->accepted, ip[n])); svz_hash_destroy (port->accepted); port->accepted = NULL; }}/* * Return the port configuration associated with the given name @var{name}. * This function returns @code{NULL} on errors. */svz_portcfg_t *svz_portcfg_get (char *name){ /* Do not handle invalid arguments. */ if (name == NULL || svz_portcfgs == NULL) return NULL; return svz_hash_get (svz_portcfgs, name);}/* * Delete the list of known port configurations. This routine should * definitely called from the core library's finalizer. */voidsvz_portcfg_finalize (void){ svz_portcfg_t **port; int n, i; if (svz_portcfgs != NULL) { n = svz_hash_size (svz_portcfgs) - 1; svz_hash_foreach_value (svz_portcfgs, port, i) { svz_portcfg_destroy (port[n]); n--; i--; } svz_hash_destroy (svz_portcfgs); svz_portcfgs = NULL; }}/* * Converts the given network address @var{str} either given in dotted * decimal form or as network interface name and saves the result in the * @code{sockaddr_in.sin_addr.s_addr} field. Return zero on success. */static intsvz_portcfg_convert_addr (char *str, struct sockaddr_in *addr){ svz_interface_t *ifc; if ((ifc = svz_interface_search (str)) != NULL) { addr->sin_addr.s_addr = ifc->ipaddr; return 0; } return svz_inet_aton (str, addr);}/* * Construct the @code{sockaddr_in} fields from the @code{ipaddr} field. * Returns zero if it worked. If it does not work the @code{ipaddr} field * did not consist of an ip address in dotted decimal form. */intsvz_portcfg_mkaddr (svz_portcfg_t *this){ int err = 0; switch (this->proto) { /* For all network protocols we assign AF_INET as protocol family, determine the network port (if necessary) and put the ip address. */ case PROTO_TCP: err = svz_portcfg_convert_addr (this->tcp_ipaddr, &this->tcp_addr); this->tcp_addr.sin_family = AF_INET; if (!(this->tcp_port > 0 && this->tcp_port < 65536)) { svz_log (LOG_ERROR, "%s: TCP port requires a short (1..65535)\n", this->name); err = -1; } else this->tcp_addr.sin_port = htons (this->tcp_port); if (this->tcp_backlog > SOMAXCONN) { svz_log (LOG_ERROR, "%s: TCP backlog out of range (1..%d)\n", this->name, SOMAXCONN); err = -1; } break; case PROTO_UDP: err = svz_portcfg_convert_addr (this->udp_ipaddr, &this->udp_addr); this->udp_addr.sin_family = AF_INET; if (!(this->udp_port > 0 && this->udp_port < 65536)) { svz_log (LOG_ERROR, "%s: UDP port requires a short (1..65535)\n", this->name); err = -1; } else this->udp_addr.sin_port = htons (this->udp_port); break; case PROTO_ICMP: err = svz_portcfg_convert_addr (this->icmp_ipaddr, &this->icmp_addr); this->icmp_addr.sin_family = AF_INET; break; case PROTO_RAW: err = svz_portcfg_convert_addr (this->raw_ipaddr, &this->raw_addr); this->raw_addr.sin_family = AF_INET; break; /* The pipe protocol needs a check for the validity of the permissions, the group and user names and its id's. */ case PROTO_PIPE: err |= svz_pipe_check_user (&this->pipe_recv); err |= svz_pipe_check_group (&this->pipe_recv); err |= svz_pipe_check_user (&this->pipe_send); err |= svz_pipe_check_group (&this->pipe_send); break; default: err = 0; } return err;}/* * Prepare the given port configuration @var{port}. Fill in default values * for yet undefined variables. */voidsvz_portcfg_prepare (svz_portcfg_t *port){ /* Check the TCP backlog value. */ if (port->proto & PROTO_TCP) { if (port->tcp_backlog <= 0 || port->tcp_backlog > SOMAXCONN) port->tcp_backlog = SOMAXCONN; } /* Check the detection barriers for pipe and tcp sockets. */ if (port->proto & (PROTO_PIPE | PROTO_TCP)) { if (port->detection_fill <= 0 || port->detection_fill > SOCK_MAX_DETECTION_FILL) port->detection_fill = SOCK_MAX_DETECTION_FILL; if (port->detection_wait <= 0 || port->detection_wait > SOCK_MAX_DETECTION_WAIT) port->detection_wait = SOCK_MAX_DETECTION_WAIT; } /* Check the initial send and receive buffer sizes. */ if (port->send_buffer_size <= 0 /* FIXME: || port->send_buffer_size >= REAL_BIG_VALUE */) { if (port->proto & (PROTO_TCP | PROTO_PIPE)) port->send_buffer_size = SEND_BUF_SIZE; else if (port->proto & PROTO_UDP) port->send_buffer_size = UDP_BUF_SIZE; else if (port->proto & (PROTO_ICMP | PROTO_RAW)) port->send_buffer_size = ICMP_BUF_SIZE; } if (port->recv_buffer_size <= 0 /* FIXME: || port->recv_buffer_size >= REAL_BIG_VALUE */) { if (port->proto & (PROTO_TCP | PROTO_PIPE)) port->recv_buffer_size = RECV_BUF_SIZE; else if (port->proto & PROTO_UDP) port->recv_buffer_size = UDP_BUF_SIZE; else if (port->proto & (PROTO_ICMP | PROTO_RAW)) port->recv_buffer_size = ICMP_BUF_SIZE; } /* Check the connection frequency. */ if (port->connect_freq <= 0) { /* FIXME: sane value is ? */ port->connect_freq = 100; }}/* * Debug helper: Emit a printable representation of the the given * port configuration to the given FILE stream @var{f}. */voidsvz_portcfg_print (svz_portcfg_t *this, FILE *f){ if (NULL == this) { fprintf (f, "portcfg is NULL\n"); return; } switch (this->proto) { case PROTO_TCP: fprintf (f, "portcfg `%s': TCP (%s|%s):%d\n", this->name, this->tcp_ipaddr, svz_inet_ntoa (this->tcp_addr.sin_addr.s_addr), this->tcp_port); break; case PROTO_UDP: fprintf (f, "portcfg `%s': UDP (%s|%s):%d\n", this->name, this->udp_ipaddr, svz_inet_ntoa (this->udp_addr.sin_addr.s_addr), this->udp_port); break; case PROTO_ICMP: fprintf (f, "portcfg `%s': ICMP (%s|%s)\n", this->name, this->icmp_ipaddr, svz_inet_ntoa (this->icmp_addr.sin_addr.s_addr)); break; case PROTO_RAW: fprintf (f, "portcfg `%s': RAW (%s|%s)\n", this->name, this->raw_ipaddr, svz_inet_ntoa (this->raw_addr.sin_addr.s_addr)); break; case PROTO_PIPE: fprintf (f, "portcfg `%s': PIPE " "(\"%s\", \"%s\" (%d), \"%s\" (%d), %04o)<->" "(\"%s\", \"%s\" (%d), \"%s\" (%d), %04o)\n", this->name, this->pipe_recv.name, this->pipe_recv.user, this->pipe_recv.uid, this->pipe_recv.group, this->pipe_recv.gid, this->pipe_recv.perm, this->pipe_send.name, this->pipe_send.user, this->pipe_send.uid, this->pipe_send.group, this->pipe_send.gid, this->pipe_send.perm); break; default: fprintf (f, "portcfg has invalid proto field %d\n", this->proto); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -