Esempio n. 1
0
/* Sync checkers activity with netlink kernel reflection */
void
update_checker_activity(uint32_t address, int enable)
{
	checker *checker_obj;
	element e;

	/* Display netlink operation */
	if (debug & 32)
		log_message(LOG_INFO, "Netlink reflector reports IP %s %s",
		       inet_ntop2(address), (enable) ? "added" : "removed");

	/* Processing Healthcheckers queue */
	if (!LIST_ISEMPTY(checkers_queue))
		for (e = LIST_HEAD(checkers_queue); e; ELEMENT_NEXT(e)) {
			checker_obj = ELEMENT_DATA(e);
			if (CHECKER_VIP(checker_obj) == address && CHECKER_HA_SUSPEND(checker_obj)) {
				if (!CHECKER_ENABLED(checker_obj) && enable)
					log_message(LOG_INFO,
					       "Activating healtchecker for service [%s:%d]",
					       inet_ntop2(CHECKER_RIP(checker_obj)),
					       ntohs(CHECKER_RPORT(checker_obj)));
				if (CHECKER_ENABLED(checker_obj) && !enable)
					log_message(LOG_INFO,
					       "Suspending healtchecker for service [%s:%d]",
					       inet_ntop2(CHECKER_RIP(checker_obj)),
					       ntohs(CHECKER_RPORT(checker_obj)));
				checker_obj->enabled = enable;
			}
		}
}
Esempio n. 2
0
int
tcp_check_thread(thread_t * thread)
{
	SOCK *sock_obj = THREAD_ARG(thread);
	int ret = 1;

	sock_obj->status =
	    tcp_socket_state(thread->u.fd, thread, req->addr_ip, req->addr_port,
			     tcp_check_thread);
	switch (sock_obj->status) {
	case connect_error:
		DBG("Error connecting server [%s:%d].\n",
		    inet_ntop2(req->addr_ip), ntohs(req->addr_port));
		thread_add_terminate_event(thread->master);
		return -1;
		break;

	case connect_timeout:
		DBG("Timeout connecting server [%s:%d].\n",
		    inet_ntop2(req->addr_ip), ntohs(req->addr_port));
		thread_add_terminate_event(thread->master);
		return -1;
		break;

	case connect_success:{
			if (req->ssl)
				ret = ssl_connect(thread);

			if (ret) {
				/* Remote WEB server is connected.
				 * Unlock eventual locked socket.
				 */
				sock_obj->lock = 0;
				thread_add_event(thread->master,
						 http_request_thread, sock_obj, 0);
			} else {
				DBG("Connection trouble to: [%s:%d].\n",
				    inet_ntop2(req->addr_ip),
				    ntohs(req->addr_port));
				if (req->ssl)
					ssl_printerr(SSL_get_error
						     (sock_obj->ssl, ret));
				sock_obj->status = connect_error;
				return -1;
			}
		}
		break;
	}

	return 1;
}
Esempio n. 3
0
enum connect_result
tcp_socket_state(int fd, thread * thread_obj, uint32_t addr_ip, uint16_t addr_port,
		 int (*func) (struct _thread *))
{
	int status;
	socklen_t slen;
	int ret = 0;
	TIMEVAL timer_min;

	/* Handle connection timeout */
	if (thread_obj->type == THREAD_WRITE_TIMEOUT) {
		DBG("TCP connection timeout to [%s:%d].",
		    inet_ntop2(addr_ip), ntohs(addr_port));
		close(thread_obj->u.fd);
		return connect_timeout;
	}

	/* Check file descriptor */
	slen = sizeof (status);
	if (getsockopt
	    (thread_obj->u.fd, SOL_SOCKET, SO_ERROR, (void *) &status, &slen) < 0)
		ret = errno;

	/* Connection failed !!! */
	if (ret) {
		DBG("TCP connection failed to [%s:%d].",
		    inet_ntop2(addr_ip), ntohs(addr_port));
		close(thread_obj->u.fd);
		return connect_error;
	}

	/* If status = 0, TCP connection to remote host is established.
	 * Otherwise register checker thread to handle connection in progress,
	 * and other error code until connection is established.
	 * Recompute the write timeout (or pending connection).
	 */
	if (status == EINPROGRESS) {
		DBG("TCP connection to [%s:%d] still IN_PROGRESS.",
		    inet_ntop2(addr_ip), ntohs(addr_port));

		timer_min = timer_sub_now(thread_obj->sands);
		thread_add_write(thread_obj->master, func, THREAD_ARG(thread_obj)
				 , thread_obj->u.fd, TIMER_LONG(timer_min));
		return connect_in_progress;
	} else if (status != 0) {
		close(thread_obj->u.fd);
		return connect_error;
	}

	return connect_success;
}
Esempio n. 4
0
static void
address_print(FILE *file, void *data)
{
	ip_address_t *ipaddr = data;
	char broadcast[INET_ADDRSTRLEN + 5] = "";	/* allow for " brd " */
	char addr_str[INET6_ADDRSTRLEN] = "";

	if (IP_IS6(ipaddr)) {
		inet_ntop(AF_INET6, &ipaddr->u.sin6_addr, addr_str, sizeof(addr_str));
	} else {
		inet_ntop(AF_INET, &ipaddr->u.sin.sin_addr, addr_str, sizeof(addr_str));
	if (ipaddr->u.sin.sin_brd.s_addr)
		snprintf(broadcast, sizeof(broadcast) - 1, " brd %s",
			 inet_ntop2(ipaddr->u.sin.sin_brd.s_addr));
	}

	fprintf(file, "     %s/%d%s dev %s%s%s%s%s\n"
		, addr_str
		, ipaddr->ifa.ifa_prefixlen
		, broadcast
		, IF_NAME(ipaddr->ifp)
		, IP_IS4(ipaddr) ? " scope " : ""
		, IP_IS4(ipaddr) ? netlink_scope_n2a(ipaddr->ifa.ifa_scope) : ""
		, ipaddr->label ? " label " : ""
		, ipaddr->label ? ipaddr->label : "");
}
Esempio n. 5
0
void
address_print(FILE *file, void *data)
{
	ip_address_t *ipaddr = data;
	char *broadcast = (char *) MALLOC(21);
	char *addr_str = (char *) MALLOC(41);

	if (IP_IS6(ipaddr)) {
		inet_ntop(AF_INET6, &ipaddr->u.sin6_addr, addr_str, 41);
	} else {
		inet_ntop(AF_INET, &ipaddr->u.sin.sin_addr, addr_str, 41);
	if (ipaddr->u.sin.sin_brd.s_addr)
		snprintf(broadcast, 20, " brd %s",
			 inet_ntop2(ipaddr->u.sin.sin_brd.s_addr));
	}

	fprintf(file, "     %s/%d%s dev %s scope %s%s%s\n"
		, addr_str
		, ipaddr->ifa.ifa_prefixlen
		, broadcast
		, IF_NAME(ipaddr->ifp)
		, netlink_scope_n2a(ipaddr->ifa.ifa_scope)
		, ipaddr->label ? " label " : ""
		, ipaddr->label ? ipaddr->label : "");
	FREE(broadcast);
	FREE(addr_str);
}
Esempio n. 6
0
/* Fill IPVS rule with root vs infos */
void
ipvs_set_rule(int cmd, virtual_server * vs, real_server * rs)
{
    /* Clean up target rule */
    memset(urule, 0, sizeof (struct ip_vs_rule_user));

    strncpy(urule->sched_name, vs->sched, IP_VS_SCHEDNAME_MAXLEN);
    urule->weight = 1;
    urule->conn_flags = vs->loadbalancing_kind;
    urule->netmask = ((u_int32_t) 0xffffffff);
    urule->protocol = vs->service_type;

    if (!parse_timeout(vs->timeout_persistence, &urule->timeout))
        log_message(LOG_INFO,
                    "IPVS : Virtual service [%s:%d] illegal timeout.",
                    inet_ntop2(SVR_IP(vs)), ntohs(SVR_PORT(vs)));

    if (urule->timeout != 0 || vs->granularity_persistence)
        urule->vs_flags = IP_VS_SVC_F_PERSISTENT;

    if (cmd == IP_VS_SO_SET_ADD || cmd == IP_VS_SO_SET_DEL)
        if (vs->granularity_persistence)
            urule->netmask = vs->granularity_persistence;

    /* SVR specific */
    if (rs) {
        if (cmd == IP_VS_SO_SET_ADDDEST
                || cmd == IP_VS_SO_SET_DELDEST
                || cmd == IP_VS_SO_SET_EDITDEST) {
            urule->weight = rs->weight;
            urule->daddr = SVR_IP(rs);
            urule->dport = SVR_PORT(rs);
        }
    }
}
Esempio n. 7
0
/* dump checker data */
static void
dump_checker(void *data_obj)
{
	checker *checker_obj = data_obj;
	log_message(LOG_INFO, " %s:%d", inet_ntop2(CHECKER_RIP(checker_obj))
	       , ntohs(CHECKER_RPORT(checker_obj)));
	(*checker_obj->dump_func) (checker_obj);
}
Esempio n. 8
0
void
if_print(FILE *file, void * data)
{
	tracked_if_t *tip = data;
	interface_t *ifp = tip->ifp;
	char addr_str[41];
	int weight = tip->weight;

	fprintf(file, "------< NIC >------\n");
	fprintf(file, " Name = %s\n", ifp->ifname);
	fprintf(file, " index = %d\n", ifp->ifindex);
	fprintf(file, " IPv4 address = %s\n",
		inet_ntop2(ifp->sin_addr.s_addr));
	inet_ntop(AF_INET6, &ifp->sin6_addr, addr_str, 41);
	fprintf(file, " IPv6 address = %s\n", addr_str);

	/* FIXME: Harcoded for ethernet */
	if (ifp->hw_type == ARPHRD_ETHER)
	fprintf(file, " MAC = %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",
		ifp->hw_addr[0], ifp->hw_addr[1], ifp->hw_addr[2]
		, ifp->hw_addr[3], ifp->hw_addr[4], ifp->hw_addr[5]);

	if (ifp->flags & IFF_UP)
		fprintf(file, " is UP\n");

	if (ifp->flags & IFF_RUNNING)
		fprintf(file, " is RUNNING\n");

	if (!(ifp->flags & IFF_UP) && !(ifp->flags & IFF_RUNNING))
		fprintf(file, " is DOWN\n");

	if (weight)
		fprintf(file, " weight = %d\n", weight);

	fprintf(file, " MTU = %d\n", ifp->mtu);

	switch (ifp->hw_type) {
	case ARPHRD_LOOPBACK:
		fprintf(file, " HW Type = LOOPBACK\n");
		break;
	case ARPHRD_ETHER:
		fprintf(file, " HW Type = ETHERNET\n");
		break;
	default:
		fprintf(file, " HW Type = UNKNOWN\n");
		break;
	}

	/* MII channel supported ? */
	if (IF_MII_SUPPORTED(ifp))
	        fprintf(file, " NIC support MII regs\n");
	else if (IF_ETHTOOL_SUPPORTED(ifp))
	        fprintf(file, " NIC support EHTTOOL GLINK interface\n");
	else
	        fprintf(file, " Enabling NIC ioctl refresh polling\n");
}
Esempio n. 9
0
void
dump_if(void *data)
{
	interface_t *ifp = data;
	char addr_str[41];

	log_message(LOG_INFO, "------< NIC >------");
	log_message(LOG_INFO, " Name = %s", ifp->ifname);
	log_message(LOG_INFO, " index = %d", ifp->ifindex);
	log_message(LOG_INFO, " IPv4 address = %s", inet_ntop2(ifp->sin_addr.s_addr));
	inet_ntop(AF_INET6, &ifp->sin6_addr, addr_str, 41);
	log_message(LOG_INFO, " IPv6 address = %s", addr_str);

	/* FIXME: Harcoded for ethernet */
	if (ifp->hw_type == ARPHRD_ETHER)
		log_message(LOG_INFO, " MAC = %.2x:%.2x:%.2x:%.2x:%.2x:%.2x",
		       ifp->hw_addr[0], ifp->hw_addr[1], ifp->hw_addr[2]
		       , ifp->hw_addr[3], ifp->hw_addr[4], ifp->hw_addr[5]);

	if (ifp->flags & IFF_UP)
		log_message(LOG_INFO, " is UP");

	if (ifp->flags & IFF_RUNNING)
		log_message(LOG_INFO, " is RUNNING");

	if (!(ifp->flags & IFF_UP) && !(ifp->flags & IFF_RUNNING))
		log_message(LOG_INFO, " is DOWN");

	log_message(LOG_INFO, " MTU = %d", ifp->mtu);

	switch (ifp->hw_type) {
	case ARPHRD_LOOPBACK:
		log_message(LOG_INFO, " HW Type = LOOPBACK");
		break;
	case ARPHRD_ETHER:
		log_message(LOG_INFO, " HW Type = ETHERNET");
		break;
	default:
		log_message(LOG_INFO, " HW Type = UNKNOWN");
		break;
	}

	/* MII channel supported ? */
	if (IF_MII_SUPPORTED(ifp))
		log_message(LOG_INFO, " NIC support MII regs");
	else if (IF_ETHTOOL_SUPPORTED(ifp))
		log_message(LOG_INFO, " NIC support EHTTOOL GLINK interface");
	else
		log_message(LOG_INFO, " Enabling NIC ioctl refresh polling");
}
Esempio n. 10
0
void
tcp_connection_state(int fd, enum connect_result status, thread * thread_obj,
		     int (*func) (struct _thread *)
		     , long timeout)
{
	checker *checker_obj;

	checker_obj = THREAD_ARG(thread_obj);

	switch (status) {
	case connect_error:
		DBG("TCP connection ERROR to [%s:%d].",
		    inet_ntop2(SVR_IP(checker_obj->rs)),
		    ntohs(SVR_PORT(checker_obj->rs)));
		close(fd);
		break;

	case connect_success:
		DBG("TCP connection SUCCESS to [%s:%d].",
		    inet_ntop2(SVR_IP(checker_obj->rs)),
		    ntohs(SVR_PORT(checker_obj->rs)));
		thread_add_write(thread_obj->master, func, checker_obj, fd, timeout);
		break;

		/* Checking non-blocking connect, we wait until socket is writable */
	case connect_in_progress:
		DBG("TCP connection to [%s:%d] now IN_PROGRESS.",
		    inet_ntop2(SVR_IP(checker_obj->rs)),
		    ntohs(SVR_PORT(checker_obj->rs)));
		thread_add_write(thread_obj->master, func, checker_obj, fd, timeout);
		break;

	default:
		break;
	}
}
Esempio n. 11
0
/* Fill IPVS rule with root vs infos */
void
ipvs_set_rule(int cmd, virtual_server * vs, real_server * rs)
{
	/* Clean target rule */
	memset(drule, 0, sizeof(ipvs_dest_t));

	drule->weight = 1;
	drule->u_threshold = 0;
	drule->l_threshold = 0;
	drule->conn_flags = vs->loadbalancing_kind;
	strncpy(srule->sched_name, vs->sched, IP_VS_SCHEDNAME_MAXLEN);
	srule->netmask = (vs->addr.ss_family == AF_INET6) ? 128 : ((u_int32_t) 0xffffffff);
	srule->protocol = vs->service_type;

	if (!parse_timeout(vs->timeout_persistence, &srule->timeout))
		log_message(LOG_INFO, "IPVS : Virtual service [%s]:%d illegal timeout."
				    , inet_ntop2(inet_sockaddrip4(&vs->addr))
				    , ntohs(inet_sockaddrport(&vs->addr)));

	srule->est_timeout = atoi(vs->est_timeout);

	if (srule->timeout != 0 || vs->granularity_persistence)
		srule->flags = IP_VS_SVC_F_PERSISTENT;

	if (cmd == IP_VS_SO_SET_ADD || cmd == IP_VS_SO_SET_DEL)
		if (vs->granularity_persistence)
			srule->netmask = vs->granularity_persistence;

	if(vs->syn_proxy)
		srule->flags |= IP_VS_SVC_F_SYNPROXY;

	/* SVR specific */
	if (rs) {
		if (cmd == IP_VS_SO_SET_ADDDEST || cmd == IP_VS_SO_SET_DELDEST ||
		    cmd == IP_VS_SO_SET_EDITDEST) {
			drule->af = rs->addr.ss_family;
			if (rs->addr.ss_family == AF_INET6)
				inet_sockaddrip6(&rs->addr, &drule->addr.in6);
			else
				drule->addr.ip = inet_sockaddrip4(&rs->addr);
			drule->port = inet_sockaddrport(&rs->addr);
			drule->weight = rs->weight;	
			drule->u_threshold = rs->u_threshold;
			drule->l_threshold = rs->l_threshold;
		}
	}
}
Esempio n. 12
0
/* register checkers to the global I/O scheduler */
void
register_checkers_thread(void)
{
	checker *checker_obj;
	element e;

	for (e = LIST_HEAD(checkers_queue); e; ELEMENT_NEXT(e)) {
		checker_obj = ELEMENT_DATA(e);
		log_message(LOG_INFO,
		       "Activating healtchecker for service [%s:%d]",
		       inet_ntop2(CHECKER_RIP(checker_obj)),
		       ntohs(CHECKER_RPORT(checker_obj)));
		CHECKER_ENABLE(checker_obj);
		if (checker_obj->launch)
			thread_add_timer(master, checker_obj->launch, checker_obj,
					 BOOTSTRAP_DELAY);
	}
}
Esempio n. 13
0
/* Asynchronous HTTP stream reader */
int
http_read_thread(thread_t * thread)
{
	SOCK *sock_obj = THREAD_ARG(thread);
	int r = 0;

	/* Handle read timeout */
	if (thread->type == THREAD_READ_TIMEOUT)
		return epilog(thread);

	/* read the HTTP stream */
	memset(sock_obj->buffer, 0, MAX_BUFFER_LENGTH);
	r = read(thread->u.fd, sock_obj->buffer + sock_obj->size,
		 MAX_BUFFER_LENGTH - sock_obj->size);

	DBG(" [l:%d,fd:%d]\n", r, sock_obj->fd);

	if (r == -1 || r == 0) {	/* -1:error , 0:EOF */
		if (r == -1) {
			/* We have encourred a real read error */
			DBG("Read error with server [%s]:%d: %s\n",
			    inet_ntop2(req->addr_ip), ntohs(req->addr_port),
			    strerror(errno));
			return epilog(thread);
		}

		/* All the HTTP stream has been parsed */
		finalize(thread);
	} else {
		/* Handle the response stream */
		http_process_stream(sock_obj, r);

		/*
		 * Register next http stream reader.
		 * Register itself to not perturbe global I/O multiplexer.
		 */
		thread_add_read(thread->master, http_read_thread, sock_obj,
				thread->u.fd, HTTP_CNX_TIMEOUT);
	}

	return 0;
}
Esempio n. 14
0
/* Send the gratuitous ARP message */
static int send_arp(ip_address_t *ipaddress)
{
	struct sockaddr_ll sll;
	int len;

	/* Build the dst device */
	memset(&sll, 0, sizeof(sll));
	sll.sll_family = AF_PACKET;
	memcpy(sll.sll_addr, IF_HWADDR(ipaddress->ifp), ETH_ALEN);
	sll.sll_halen = ETHERNET_HW_LEN;
	sll.sll_ifindex = IF_INDEX(ipaddress->ifp);

	/* Send packet */
	len = sendto(garp_fd, garp_buffer, sizeof(arphdr_t) + ETHER_HDR_LEN
		     , 0, (struct sockaddr *)&sll, sizeof(sll));
	if (len < 0)
		log_message(LOG_INFO, "Error sending gratuitous ARP on %s for %s",
			    IF_NAME(ipaddress->ifp), inet_ntop2(ipaddress->u.sin.sin_addr.s_addr));
	return len;
}
Esempio n. 15
0
void
dump_ipaddress(void *if_data)
{
	ip_address_t *ipaddr = if_data;
	char broadcast[INET_ADDRSTRLEN + 5] = "";

	if (!IP_IS6(ipaddr) && ipaddr->u.sin.sin_brd.s_addr) {
		snprintf(broadcast, 21, " brd %s",
			 inet_ntop2(ipaddr->u.sin.sin_brd.s_addr));
	}

	log_message(LOG_INFO, "     %s/%d%s dev %s scope %s%s%s"
			    , ipaddresstos(NULL, ipaddr)
			    , ipaddr->ifa.ifa_prefixlen
			    , broadcast
			    , IF_NAME(ipaddr->ifp)
			    , get_rttables_scope(ipaddr->ifa.ifa_scope)
			    , ipaddr->label ? " label " : ""
			    , ipaddr->label ? ipaddr->label : "");
}
Esempio n. 16
0
/* remote Web server is connected, send it the get url query.  */
int
http_request_thread(thread_t * thread)
{
	SOCK *sock_obj = THREAD_ARG(thread);
	char *str_request;
	char *request_host;
	char *request_host_port;
	int ret = 0;

	/* Handle read timeout */
	if (thread->type == THREAD_WRITE_TIMEOUT)
		return epilog(thread);

	/* Allocate & clean the GET string */
	str_request = (char *) MALLOC(GET_BUFFER_LENGTH);
	memset(str_request, 0, GET_BUFFER_LENGTH);

	if (req->vhost) {
		/* If vhost was defined we don't need to override it's port */
		request_host = req->vhost;
		request_host_port = (char*) MALLOC(1);
		*request_host_port = 0;
	} else {
		request_host = inet_ntop2(req->addr_ip);
	
		/* Allocate a buffer for the port string ( ":" [0-9][0-9][0-9][0-9][0-9] "\0" ) */
		request_host_port = (char*) MALLOC(7);
		snprintf(request_host_port, 7, ":%d",
		 ntohs(req->addr_port));
	}
	
	snprintf(str_request, GET_BUFFER_LENGTH, REQUEST_TEMPLATE,
		 req->url, request_host, request_host_port);
	
	FREE(request_host_port);

	/* Send the GET request to remote Web server */
	DBG("Sending GET request [%s] on fd:%d\n", req->url, sock_obj->fd);
	if (req->ssl)
		ret =
		    ssl_send_request(sock_obj->ssl, str_request,
				     strlen(str_request));
	else
		ret =
		    (send(sock_obj->fd, str_request, strlen(str_request), 0) !=
		     -1) ? 1 : 0;

	FREE(str_request);

	if (!ret) {
		fprintf(stderr, "Cannot send get request to [%s]:%d.\n",
			inet_ntop2(req->addr_ip)
			, ntohs(req->addr_port));
		return epilog(thread);
	}

	/* Register read timeouted thread */
	thread_add_read(thread->master, http_response_thread, sock_obj,
			sock_obj->fd, HTTP_CNX_TIMEOUT);
	return 1;
}
Esempio n. 17
0
int
ipvs_cmd(int cmd, list vs_group, virtual_server * vs, real_server * rs)
{
    struct ip_masq_ctl ctl;
    int result = 0;
    int sockfd;

    memset(&ctl, 0, sizeof (struct ip_masq_ctl));

    ctl.m_target = IP_MASQ_TARGET_VS;
    ctl.m_cmd = cmd;
    strncpy(ctl.m_tname, vs->sched, IP_MASQ_TNAME_MAX);
    ctl.u.vs_user.weight = -1;
    ctl.u.vs_user.masq_flags = vs->loadbalancing_kind;
    ctl.u.vs_user.netmask = ((u_int32_t) 0xffffffff);
    ctl.u.vs_user.protocol = vs->service_type;

    if (!parse_timeout(vs->timeout_persistence, &ctl.u.vs_user.timeout))
        log_message(LOG_INFO,
                    "IPVS : Virtual service [%s:%d] illegal timeout.",
                    inet_ntop2(SVR_IP(vs))
                    , ntohs(SVR_PORT(vs)));
    if (ctl.u.vs_user.timeout != 0 || vs->granularity_persistence)
        ctl.u.vs_user.vs_flags = IP_VS_SVC_F_PERSISTENT;

    /* VS specific */
    if (vs->vfwmark) {
        ctl.u.vs_user.vfwmark = vs->vfwmark;
    } else {
        ctl.u.vs_user.vaddr = SVR_IP(vs);
        ctl.u.vs_user.vport = SVR_PORT(vs);
    }

    if (ctl.m_cmd == IP_MASQ_CMD_ADD || ctl.m_cmd == IP_MASQ_CMD_DEL)
        if (vs->granularity_persistence)
            ctl.u.vs_user.netmask = vs->granularity_persistence;

    /* SVR specific */
    if (ctl.m_cmd == IP_MASQ_CMD_ADD_DEST
            || ctl.m_cmd == IP_MASQ_CMD_DEL_DEST
            || ctl.m_cmd == IP_MASQ_CMD_SET_DEST) {
        ctl.u.vs_user.weight = rs->weight;
        ctl.u.vs_user.daddr = SVR_IP(rs);
        ctl.u.vs_user.dport = SVR_PORT(rs);
    }

    /* Does the service use inhibit flag ? */
    if (ctl.m_cmd == IP_MASQ_CMD_DEL_DEST && rs->inhibit) {
        ctl.m_cmd = IP_MASQ_CMD_SET_DEST;
        ctl.u.vs_user.weight = 0;
    }
    if (ctl.m_cmd == IP_MASQ_CMD_ADD_DEST && rs->inhibit && !rs->alive)
        ctl.m_cmd = IP_MASQ_CMD_SET_DEST;

    sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
    if (sockfd == -1) {
        log_message(LOG_INFO,
                    "IPVS : Can not initialize SOCK_RAW descriptor.");
        return IPVS_ERROR;
    }

    result =
        setsockopt(sockfd, IPPROTO_IP, IP_FW_MASQ_CTL, (char *) &ctl,
                   sizeof (ctl));

    if (errno == ESRCH) {
        log_message(LOG_INFO, "IPVS : Virtual service [%s:%d] not defined.",
                    inet_ntop2(SVR_IP(vs))
                    , ntohs(SVR_PORT(vs)));
        close(sockfd);
        return IPVS_ERROR;
    } else if (errno == EEXIST) {
        if (rs)
            log_message(LOG_INFO,
                        "IPVS : Destination already exists [%s:%d].",
                        inet_ntop2(SVR_IP(rs))
                        , ntohs(SVR_PORT(rs)));
    } else if (errno == ENOENT) {
        if (rs)
            log_message(LOG_INFO, "IPVS : No such destination [%s:%d].",
                        inet_ntop2(SVR_IP(rs))
                        , ntohs(SVR_PORT(rs)));
    }

    close(sockfd);
    return IPVS_SUCCESS;
}
Esempio n. 18
0
static void
dump_if(void *data)
{
	interface_t *ifp = data;
#ifdef _HAVE_VRRP_VMAC_
	interface_t *ifp_u;
#endif
	char addr_str[INET6_ADDRSTRLEN];

	log_message(LOG_INFO, "------< NIC >------");
	log_message(LOG_INFO, " Name = %s", ifp->ifname);
	log_message(LOG_INFO, " index = %d", ifp->ifindex);
	log_message(LOG_INFO, " IPv4 address = %s", inet_ntop2(ifp->sin_addr.s_addr));
	inet_ntop(AF_INET6, &ifp->sin6_addr, addr_str, sizeof(addr_str));
	log_message(LOG_INFO, " IPv6 address = %s", addr_str);

	/* FIXME: Hardcoded for ethernet */
	if (ifp->hw_type == ARPHRD_ETHER)
		log_message(LOG_INFO, " MAC = %.2x:%.2x:%.2x:%.2x:%.2x:%.2x",
		       ifp->hw_addr[0], ifp->hw_addr[1], ifp->hw_addr[2]
		       , ifp->hw_addr[3], ifp->hw_addr[4], ifp->hw_addr[5]);

	if (ifp->flags & IFF_UP)
		log_message(LOG_INFO, " is UP");

	if (ifp->flags & IFF_RUNNING)
		log_message(LOG_INFO, " is RUNNING");

	if (!(ifp->flags & IFF_UP) && !(ifp->flags & IFF_RUNNING))
		log_message(LOG_INFO, " is DOWN");

	log_message(LOG_INFO, " MTU = %d", ifp->mtu);

	switch (ifp->hw_type) {
	case ARPHRD_LOOPBACK:
		log_message(LOG_INFO, " HW Type = LOOPBACK");
		break;
	case ARPHRD_ETHER:
		log_message(LOG_INFO, " HW Type = ETHERNET");
		break;
	default:
		log_message(LOG_INFO, " HW Type = UNKNOWN");
		break;
	}

#ifdef _HAVE_VRRP_VMAC_
	if (ifp->vmac && (ifp_u = if_get_by_ifindex(ifp->base_ifindex)))
		log_message(LOG_INFO, " VMAC underlying interface = %s", ifp_u->ifname);
#endif

	/* MII channel supported ? */
	if (IF_MII_SUPPORTED(ifp))
		log_message(LOG_INFO, " NIC support MII regs");
	else if (IF_ETHTOOL_SUPPORTED(ifp))
		log_message(LOG_INFO, " NIC support EHTTOOL GLINK interface");
	else
		log_message(LOG_INFO, " Enabling NIC ioctl refresh polling");

	if (ifp->garp_delay) {
		if (ifp->garp_delay->have_garp_interval)
			log_message(LOG_INFO, " Gratuitous ARP interval %ldms",
				    ifp->garp_delay->garp_interval.tv_sec * 100 +
				     ifp->garp_delay->garp_interval.tv_usec / (TIMER_HZ / 100));

		if (ifp->garp_delay->have_gna_interval)
			log_message(LOG_INFO, " Gratuitous NA interval %ldms",
				    ifp->garp_delay->gna_interval.tv_sec * 100 +
				     ifp->garp_delay->gna_interval.tv_usec / (TIMER_HZ / 100));
		if (ifp->garp_delay->aggregation_group)
			log_message(LOG_INFO, " Gratuitous ARP aggregation group %d", ifp->garp_delay->aggregation_group);
	}
}
Esempio n. 19
0
int
misc_check_child_thread(thread * thread_obj)
{
	int wait_status;
	checker *checker_obj;
	misc_checker *misc_chk;

	checker_obj = THREAD_ARG(thread_obj);
	misc_chk = CHECKER_ARG(checker_obj);

	if (thread_obj->type == THREAD_CHILD_TIMEOUT) {
		pid_t pid;

		pid = THREAD_CHILD_PID(thread_obj);

		/* The child hasn't responded. Kill it off. */
		if (svr_checker_up(checker_obj->id, checker_obj->rs)) {
			log_message(LOG_INFO, "Misc check to [%s] for [%s] timed out",
			       inet_ntop2(CHECKER_RIP(checker_obj)),
			       misc_chk->path);
			smtp_alert(checker_obj->rs, NULL, NULL,
				   "DOWN",
				   "=> MISC CHECK script timeout on service <=");
			update_svr_checker_state(DOWN, checker_obj->id
						     , checker_obj->vs
						     , checker_obj->rs);
		}

		kill(pid, SIGTERM);
		thread_add_child(thread_obj->master, misc_check_child_timeout_thread,
				 checker_obj, pid, 2);
		return 0;
	}

	wait_status = THREAD_CHILD_STATUS(thread_obj);

	if (WIFEXITED(wait_status)) {
		int status;
		status = WEXITSTATUS(wait_status);
		if (status == 0 ||
                    (misc_chk->dynamic == 1 && status >= 2 && status <= 255)) {
			/*
			 * The actual weight set when using misc_dynamic is two less than
			 * the exit status returned.  Effective range is 0..253.
			 * Catch legacy case of status being 0 but misc_dynamic being set.
			 */
			if (misc_chk->dynamic == 1 && status != 0)
				update_svr_wgt(status - 2, checker_obj->vs, checker_obj->rs);

			/* everything is good */
			if (!svr_checker_up(checker_obj->id, checker_obj->rs)) {
				log_message(LOG_INFO, "Misc check to [%s] for [%s] success.",
				       inet_ntop2(CHECKER_RIP(checker_obj)),
				       misc_chk->path);
				smtp_alert(checker_obj->rs, NULL, NULL,
					   "UP",
					   "=> MISC CHECK succeed on service <=");
				update_svr_checker_state(UP, checker_obj->id
							   , checker_obj->vs
							   , checker_obj->rs);
			}
		} else {
			if (svr_checker_up(checker_obj->id, checker_obj->rs)) {
				log_message(LOG_INFO, "Misc check to [%s] for [%s] failed.",
				       inet_ntop2(CHECKER_RIP(checker_obj)),
				       misc_chk->path);
				smtp_alert(checker_obj->rs, NULL, NULL,
					   "DOWN",
					   "=> MISC CHECK failed on service <=");
				update_svr_checker_state(DOWN, checker_obj->id
							     , checker_obj->vs
							     , checker_obj->rs);
			}
		}
	}

	return 0;
}