|
Packit |
61cb5a |
/*
|
|
Packit |
61cb5a |
* Copyright (c) 2010-2011, Red Hat, Inc.
|
|
Packit |
61cb5a |
*
|
|
Packit |
61cb5a |
* Permission to use, copy, modify, and/or distribute this software for any
|
|
Packit |
61cb5a |
* purpose with or without fee is hereby granted, provided that the above
|
|
Packit |
61cb5a |
* copyright notice and this permission notice appear in all copies.
|
|
Packit |
61cb5a |
*
|
|
Packit |
61cb5a |
* THE SOFTWARE IS PROVIDED "AS IS" AND RED HAT, INC. DISCLAIMS ALL WARRANTIES
|
|
Packit |
61cb5a |
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
|
Packit |
61cb5a |
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL RED HAT, INC. BE LIABLE
|
|
Packit |
61cb5a |
* FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
Packit |
61cb5a |
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
|
Packit |
61cb5a |
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
|
Packit |
61cb5a |
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
Packit |
61cb5a |
*/
|
|
Packit |
61cb5a |
|
|
Packit |
61cb5a |
/*
|
|
Packit |
61cb5a |
* Author: Jan Friesse <jfriesse@redhat.com>
|
|
Packit |
61cb5a |
*/
|
|
Packit |
61cb5a |
|
|
Packit |
61cb5a |
#include <sys/types.h>
|
|
Packit |
61cb5a |
|
|
Packit |
61cb5a |
#include <sys/socket.h>
|
|
Packit |
61cb5a |
|
|
Packit |
61cb5a |
#include <net/if.h>
|
|
Packit |
61cb5a |
#include <netinet/in.h>
|
|
Packit |
61cb5a |
#include <arpa/inet.h>
|
|
Packit |
61cb5a |
|
|
Packit |
61cb5a |
#include <err.h>
|
|
Packit |
61cb5a |
#include <limits.h>
|
|
Packit |
61cb5a |
#include <stdio.h>
|
|
Packit |
61cb5a |
#include <stdlib.h>
|
|
Packit |
61cb5a |
#include <string.h>
|
|
Packit |
61cb5a |
#include <stdarg.h>
|
|
Packit |
61cb5a |
|
|
Packit |
61cb5a |
#include "rhfunc.h"
|
|
Packit |
61cb5a |
#include "omping.h"
|
|
Packit |
61cb5a |
|
|
Packit |
61cb5a |
/*
|
|
Packit |
61cb5a |
* Add item to remote host list. Addr pointer is stored in rh_item. On fail, function returns NULL,
|
|
Packit |
61cb5a |
* otherwise newly allocated rh_item is returned. dup_buf_items is number of items to be stored in
|
|
Packit |
61cb5a |
* duplicate buffers. rate_limit_time is maximum time between two received packets.
|
|
Packit |
61cb5a |
*/
|
|
Packit |
61cb5a |
struct rh_item *
|
|
Packit |
61cb5a |
rh_list_add_item(struct rh_list *rh_list, struct ai_item *addr, int dup_buf_items,
|
|
Packit |
61cb5a |
int rate_limit_time)
|
|
Packit |
61cb5a |
{
|
|
Packit |
61cb5a |
struct rh_item *rh_item;
|
|
Packit |
61cb5a |
struct rh_item_ci *ci;
|
|
Packit |
61cb5a |
int i;
|
|
Packit |
61cb5a |
|
|
Packit |
61cb5a |
rh_item = (struct rh_item *)malloc(sizeof(struct rh_item));
|
|
Packit |
61cb5a |
if (rh_item == NULL) {
|
|
Packit |
61cb5a |
return (NULL);
|
|
Packit |
61cb5a |
}
|
|
Packit |
61cb5a |
|
|
Packit |
61cb5a |
memset(rh_item, 0, sizeof(struct rh_item));
|
|
Packit |
61cb5a |
|
|
Packit |
61cb5a |
rh_item->addr = addr;
|
|
Packit |
61cb5a |
ci = &rh_item->client_info;
|
|
Packit |
61cb5a |
|
|
Packit |
61cb5a |
if (dup_buf_items > 0) {
|
|
Packit |
61cb5a |
ci->dup_buf_items = dup_buf_items;
|
|
Packit |
61cb5a |
|
|
Packit |
61cb5a |
for (i = 0; i < 2; i++) {
|
|
Packit |
61cb5a |
ci->dup_buffer[i] = (uint32_t *)malloc(dup_buf_items * sizeof(uint32_t));
|
|
Packit |
61cb5a |
|
|
Packit |
61cb5a |
if (ci->dup_buffer[i] == NULL) {
|
|
Packit |
61cb5a |
goto malloc_error;
|
|
Packit |
61cb5a |
}
|
|
Packit |
61cb5a |
|
|
Packit |
61cb5a |
memset(ci->dup_buffer[i], 0, dup_buf_items * sizeof(uint32_t));
|
|
Packit |
61cb5a |
}
|
|
Packit |
61cb5a |
}
|
|
Packit |
61cb5a |
|
|
Packit |
61cb5a |
if (rate_limit_time > 0) {
|
|
Packit |
61cb5a |
gcra_init(&rh_item->server_info.gcra, rate_limit_time, GCRA_BURST);
|
|
Packit |
61cb5a |
}
|
|
Packit |
61cb5a |
|
|
Packit |
61cb5a |
TAILQ_INSERT_TAIL(rh_list, rh_item, entries);
|
|
Packit |
61cb5a |
|
|
Packit |
61cb5a |
return (rh_item);
|
|
Packit |
61cb5a |
|
|
Packit |
61cb5a |
malloc_error:
|
|
Packit |
61cb5a |
for (i = 0; i < 2; i++) {
|
|
Packit |
61cb5a |
free(rh_item->client_info.dup_buffer[i]);
|
|
Packit |
61cb5a |
}
|
|
Packit |
61cb5a |
free(rh_item);
|
|
Packit |
61cb5a |
|
|
Packit |
61cb5a |
return (NULL);
|
|
Packit |
61cb5a |
}
|
|
Packit |
61cb5a |
|
|
Packit |
61cb5a |
/*
|
|
Packit |
61cb5a |
* Create list of rh_items. It's also possible to pass ai_list to include every address from list to
|
|
Packit |
61cb5a |
* newly allocated rh_list. dup_buf_items is number of items to be stored in duplicate buffers.
|
|
Packit |
61cb5a |
* rate_limit_time is maximum time between two received packets.
|
|
Packit |
61cb5a |
*/
|
|
Packit |
61cb5a |
void
|
|
Packit |
61cb5a |
rh_list_create(struct rh_list *rh_list, struct ai_list *remote_addrs, int dup_buf_items,
|
|
Packit |
61cb5a |
int rate_limit_time)
|
|
Packit |
61cb5a |
{
|
|
Packit |
61cb5a |
struct ai_item *addr;
|
|
Packit |
61cb5a |
struct rh_item *rh_item;
|
|
Packit |
61cb5a |
|
|
Packit |
61cb5a |
TAILQ_INIT(rh_list);
|
|
Packit |
61cb5a |
|
|
Packit |
61cb5a |
if (remote_addrs != NULL) {
|
|
Packit |
61cb5a |
TAILQ_FOREACH(addr, remote_addrs, entries) {
|
|
Packit |
61cb5a |
rh_item = rh_list_add_item(rh_list, addr, dup_buf_items, rate_limit_time);
|
|
Packit |
61cb5a |
if (rh_item == NULL) {
|
|
Packit |
61cb5a |
errx(1, "Can't alloc memory");
|
|
Packit |
61cb5a |
}
|
|
Packit |
61cb5a |
}
|
|
Packit |
61cb5a |
}
|
|
Packit |
61cb5a |
}
|
|
Packit |
61cb5a |
|
|
Packit |
61cb5a |
/*
|
|
Packit |
61cb5a |
* Find remote host with addr sa in list. rh_item pointer is returned on success otherwise NULL is
|
|
Packit |
61cb5a |
* returned.
|
|
Packit |
61cb5a |
*/
|
|
Packit |
61cb5a |
struct rh_item *
|
|
Packit |
61cb5a |
rh_list_find(struct rh_list *rh_list, const struct sockaddr *sa)
|
|
Packit |
61cb5a |
{
|
|
Packit |
61cb5a |
struct rh_item *rh_item;
|
|
Packit |
61cb5a |
|
|
Packit |
61cb5a |
TAILQ_FOREACH(rh_item, rh_list, entries) {
|
|
Packit |
61cb5a |
if (af_sockaddr_eq((const struct sockaddr *)&rh_item->addr->sas, sa))
|
|
Packit |
61cb5a |
return (rh_item);
|
|
Packit |
61cb5a |
}
|
|
Packit |
61cb5a |
|
|
Packit |
61cb5a |
return (NULL);
|
|
Packit |
61cb5a |
}
|
|
Packit |
61cb5a |
|
|
Packit |
61cb5a |
/*
|
|
Packit |
61cb5a |
* Free list from memory.
|
|
Packit |
61cb5a |
*/
|
|
Packit |
61cb5a |
void
|
|
Packit |
61cb5a |
rh_list_free(struct rh_list *rh_list)
|
|
Packit |
61cb5a |
{
|
|
Packit |
61cb5a |
struct rh_item *rh_item;
|
|
Packit |
61cb5a |
struct rh_item *rh_item_next;
|
|
Packit |
61cb5a |
int i;
|
|
Packit |
61cb5a |
|
|
Packit |
61cb5a |
rh_item = TAILQ_FIRST(rh_list);
|
|
Packit |
61cb5a |
|
|
Packit |
61cb5a |
while (rh_item != NULL) {
|
|
Packit |
61cb5a |
rh_item_next = TAILQ_NEXT(rh_item, entries);
|
|
Packit |
61cb5a |
|
|
Packit |
61cb5a |
free(rh_item->client_info.server_info);
|
|
Packit |
61cb5a |
free(rh_item->client_info.ses_id);
|
|
Packit |
61cb5a |
|
|
Packit |
61cb5a |
for (i = 0; i < 2; i++) {
|
|
Packit |
61cb5a |
free(rh_item->client_info.dup_buffer[i]);
|
|
Packit |
61cb5a |
}
|
|
Packit |
61cb5a |
|
|
Packit |
61cb5a |
free(rh_item);
|
|
Packit |
61cb5a |
|
|
Packit |
61cb5a |
rh_item = rh_item_next;
|
|
Packit |
61cb5a |
}
|
|
Packit |
61cb5a |
|
|
Packit |
61cb5a |
TAILQ_INIT(rh_list);
|
|
Packit |
61cb5a |
}
|
|
Packit |
61cb5a |
|
|
Packit |
61cb5a |
/*
|
|
Packit |
61cb5a |
* Generate CID for all items in rh_list
|
|
Packit |
61cb5a |
*/
|
|
Packit |
61cb5a |
void
|
|
Packit |
61cb5a |
rh_list_gen_cid(struct rh_list *rh_list, const struct ai_item *local_addr)
|
|
Packit |
61cb5a |
{
|
|
Packit |
61cb5a |
struct rh_item *rh_item;
|
|
Packit |
61cb5a |
|
|
Packit |
61cb5a |
TAILQ_FOREACH(rh_item, rh_list, entries) {
|
|
Packit |
61cb5a |
util_gen_cid(rh_item->client_info.client_id, local_addr);
|
|
Packit |
61cb5a |
}
|
|
Packit |
61cb5a |
}
|
|
Packit |
61cb5a |
|
|
Packit |
61cb5a |
/*
|
|
Packit |
61cb5a |
* Return length of longest host name from rh_list list.
|
|
Packit |
61cb5a |
*/
|
|
Packit |
61cb5a |
int
|
|
Packit |
61cb5a |
rh_list_hn_max_len(struct rh_list *rh_list)
|
|
Packit |
61cb5a |
{
|
|
Packit |
61cb5a |
struct rh_item *rh_item;
|
|
Packit |
61cb5a |
size_t max_len;
|
|
Packit |
61cb5a |
|
|
Packit |
61cb5a |
max_len = 0;
|
|
Packit |
61cb5a |
TAILQ_FOREACH(rh_item, rh_list, entries) {
|
|
Packit |
61cb5a |
if (strlen(rh_item->addr->host_name) > max_len) {
|
|
Packit |
61cb5a |
max_len = strlen(rh_item->addr->host_name);
|
|
Packit |
61cb5a |
}
|
|
Packit |
61cb5a |
}
|
|
Packit |
61cb5a |
|
|
Packit |
61cb5a |
return (max_len > INT_MAX ? INT_MAX : (int)max_len);
|
|
Packit |
61cb5a |
}
|
|
Packit |
61cb5a |
|
|
Packit |
61cb5a |
/*
|
|
Packit |
61cb5a |
* Return number of items in rh_list.
|
|
Packit |
61cb5a |
*/
|
|
Packit |
61cb5a |
unsigned int
|
|
Packit |
61cb5a |
rh_list_length(const struct rh_list *rh_list)
|
|
Packit |
61cb5a |
{
|
|
Packit |
61cb5a |
struct rh_item *rh_item;
|
|
Packit |
61cb5a |
unsigned int res;
|
|
Packit |
61cb5a |
|
|
Packit |
61cb5a |
res = 0;
|
|
Packit |
61cb5a |
|
|
Packit |
61cb5a |
TAILQ_FOREACH(rh_item, rh_list, entries) {
|
|
Packit |
61cb5a |
res++;
|
|
Packit |
61cb5a |
}
|
|
Packit |
61cb5a |
|
|
Packit |
61cb5a |
return (res);
|
|
Packit |
61cb5a |
}
|
|
Packit |
61cb5a |
|
|
Packit |
61cb5a |
/*
|
|
Packit |
61cb5a |
* Move all items in rh_list to finish state. fs is which part of remote host is put to finish
|
|
Packit |
61cb5a |
* state. This may mean, that server state is put to RH_SS_FINISHING and/or client state is moved
|
|
Packit |
61cb5a |
* to RH_CS_STOP
|
|
Packit |
61cb5a |
*/
|
|
Packit |
61cb5a |
void
|
|
Packit |
61cb5a |
rh_list_put_to_finish_state(struct rh_list *rh_list, enum rh_list_finish_state fs)
|
|
Packit |
61cb5a |
{
|
|
Packit |
61cb5a |
struct rh_item *rh_item;
|
|
Packit |
61cb5a |
|
|
Packit |
61cb5a |
TAILQ_FOREACH(rh_item, rh_list, entries) {
|
|
Packit |
61cb5a |
if (fs == RH_LFS_SERVER || fs == RH_LFS_BOTH) {
|
|
Packit |
61cb5a |
rh_item->server_info.state = RH_SS_FINISHING;
|
|
Packit |
61cb5a |
}
|
|
Packit |
61cb5a |
if (fs == RH_LFS_CLIENT || fs == RH_LFS_BOTH) {
|
|
Packit |
61cb5a |
rh_item->client_info.state = RH_CS_STOP;
|
|
Packit |
61cb5a |
}
|
|
Packit |
61cb5a |
}
|
|
Packit |
61cb5a |
}
|