|
Packit Service |
5956c7 |
/*
|
|
Packit Service |
5956c7 |
* Soft: Keepalived is a failover program for the LVS project
|
|
Packit Service |
5956c7 |
* <www.linuxvirtualserver.org>. It monitor & manipulate
|
|
Packit Service |
5956c7 |
* a loadbalanced server pool using multi-layer checks.
|
|
Packit Service |
5956c7 |
*
|
|
Packit Service |
5956c7 |
* Part: utils.h include file.
|
|
Packit Service |
5956c7 |
*
|
|
Packit Service |
5956c7 |
* Author: Alexandre Cassen, <acassen@linux-vs.org>
|
|
Packit Service |
5956c7 |
*
|
|
Packit Service |
5956c7 |
* This program is distributed in the hope that it will be useful,
|
|
Packit Service |
5956c7 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit Service |
5956c7 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
Packit Service |
5956c7 |
* See the GNU General Public License for more details.
|
|
Packit Service |
5956c7 |
*
|
|
Packit Service |
5956c7 |
* This program is free software; you can redistribute it and/or
|
|
Packit Service |
5956c7 |
* modify it under the terms of the GNU General Public License
|
|
Packit Service |
5956c7 |
* as published by the Free Software Foundation; either version
|
|
Packit Service |
5956c7 |
* 2 of the License, or (at your option) any later version.
|
|
Packit Service |
5956c7 |
*
|
|
Packit Service |
5956c7 |
* Copyright (C) 2001-2017 Alexandre Cassen, <acassen@gmail.com>
|
|
Packit Service |
5956c7 |
*/
|
|
Packit Service |
5956c7 |
|
|
Packit Service |
5956c7 |
#ifndef _UTILS_H
|
|
Packit Service |
5956c7 |
#define _UTILS_H
|
|
Packit Service |
5956c7 |
|
|
Packit Service |
5956c7 |
#include "config.h"
|
|
Packit Service |
5956c7 |
|
|
Packit Service |
5956c7 |
/* system includes */
|
|
Packit Service |
5956c7 |
#include <sys/types.h>
|
|
Packit Service |
5956c7 |
#include <stdint.h>
|
|
Packit Service |
5956c7 |
#include <stdbool.h>
|
|
Packit Service |
5956c7 |
#include <sys/socket.h>
|
|
Packit Service |
5956c7 |
#include <netinet/in.h>
|
|
Packit Service |
5956c7 |
#include <stdio.h>
|
|
Packit Service |
5956c7 |
|
|
Packit Service |
5956c7 |
#include "vector.h"
|
|
Packit Service |
5956c7 |
#ifdef _DEBUG_
|
|
Packit Service |
5956c7 |
#include "logger.h"
|
|
Packit Service |
5956c7 |
#endif
|
|
Packit Service |
5956c7 |
|
|
Packit Service |
5956c7 |
/* Global debugging logging facilities */
|
|
Packit Service |
5956c7 |
#ifdef _DEBUG_
|
|
Packit Service |
5956c7 |
#define DBG(fmt, msg...) log_message(LOG_DEBUG, fmt, ## msg)
|
|
Packit Service |
5956c7 |
#else
|
|
Packit Service |
5956c7 |
#define DBG(fmt, msg...)
|
|
Packit Service |
5956c7 |
#endif
|
|
Packit Service |
5956c7 |
|
|
Packit Service |
5956c7 |
#define STR(x) #x
|
|
Packit Service |
5956c7 |
|
|
Packit Service |
5956c7 |
#ifdef _WITH_PERF_
|
|
Packit Service |
5956c7 |
typedef enum {
|
|
Packit Service |
5956c7 |
PERF_NONE,
|
|
Packit Service |
5956c7 |
PERF_RUN,
|
|
Packit Service |
5956c7 |
PERF_ALL,
|
|
Packit Service |
5956c7 |
PERF_END,
|
|
Packit Service |
5956c7 |
} perf_t;
|
|
Packit Service |
5956c7 |
#endif
|
|
Packit Service |
5956c7 |
|
|
Packit Service |
5956c7 |
/* inline stuff */
|
|
Packit Service |
5956c7 |
static inline int __ip6_addr_equal(const struct in6_addr *a1,
|
|
Packit Service |
5956c7 |
const struct in6_addr *a2)
|
|
Packit Service |
5956c7 |
{
|
|
Packit Service |
5956c7 |
return (((a1->s6_addr32[0] ^ a2->s6_addr32[0]) |
|
|
Packit Service |
5956c7 |
(a1->s6_addr32[1] ^ a2->s6_addr32[1]) |
|
|
Packit Service |
5956c7 |
(a1->s6_addr32[2] ^ a2->s6_addr32[2]) |
|
|
Packit Service |
5956c7 |
(a1->s6_addr32[3] ^ a2->s6_addr32[3])) == 0);
|
|
Packit Service |
5956c7 |
}
|
|
Packit Service |
5956c7 |
|
|
Packit Service |
5956c7 |
static inline bool sockstorage_equal(const struct sockaddr_storage *s1,
|
|
Packit Service |
5956c7 |
const struct sockaddr_storage *s2)
|
|
Packit Service |
5956c7 |
{
|
|
Packit Service |
5956c7 |
if (s1->ss_family != s2->ss_family)
|
|
Packit Service |
5956c7 |
return false;
|
|
Packit Service |
5956c7 |
|
|
Packit Service |
5956c7 |
if (s1->ss_family == AF_INET6) {
|
|
Packit Service |
5956c7 |
struct sockaddr_in6 *a1 = (struct sockaddr_in6 *) s1;
|
|
Packit Service |
5956c7 |
struct sockaddr_in6 *a2 = (struct sockaddr_in6 *) s2;
|
|
Packit Service |
5956c7 |
|
|
Packit Service |
5956c7 |
// if (IN6_ARE_ADDR_EQUAL(a1, a2) && (a1->sin6_port == a2->sin6_port))
|
|
Packit Service |
5956c7 |
if (__ip6_addr_equal(&a1->sin6_addr, &a2->sin6_addr) &&
|
|
Packit Service |
5956c7 |
(a1->sin6_port == a2->sin6_port))
|
|
Packit Service |
5956c7 |
return true;
|
|
Packit Service |
5956c7 |
} else if (s1->ss_family == AF_INET) {
|
|
Packit Service |
5956c7 |
struct sockaddr_in *a1 = (struct sockaddr_in *) s1;
|
|
Packit Service |
5956c7 |
struct sockaddr_in *a2 = (struct sockaddr_in *) s2;
|
|
Packit Service |
5956c7 |
|
|
Packit Service |
5956c7 |
if ((a1->sin_addr.s_addr == a2->sin_addr.s_addr) &&
|
|
Packit Service |
5956c7 |
(a1->sin_port == a2->sin_port))
|
|
Packit Service |
5956c7 |
return true;
|
|
Packit Service |
5956c7 |
} else if (s1->ss_family == AF_UNSPEC)
|
|
Packit Service |
5956c7 |
return true;
|
|
Packit Service |
5956c7 |
|
|
Packit Service |
5956c7 |
return false;
|
|
Packit Service |
5956c7 |
}
|
|
Packit Service |
5956c7 |
|
|
Packit Service |
5956c7 |
static inline bool inaddr_equal(sa_family_t family, void *addr1, void *addr2)
|
|
Packit Service |
5956c7 |
{
|
|
Packit Service |
5956c7 |
if (family == AF_INET6) {
|
|
Packit Service |
5956c7 |
struct in6_addr *a1 = (struct in6_addr *) addr1;
|
|
Packit Service |
5956c7 |
struct in6_addr *a2 = (struct in6_addr *) addr2;
|
|
Packit Service |
5956c7 |
|
|
Packit Service |
5956c7 |
if (__ip6_addr_equal(a1, a2))
|
|
Packit Service |
5956c7 |
return true;
|
|
Packit Service |
5956c7 |
} else if (family == AF_INET) {
|
|
Packit Service |
5956c7 |
struct in_addr *a1 = (struct in_addr *) addr1;
|
|
Packit Service |
5956c7 |
struct in_addr *a2 = (struct in_addr *) addr2;
|
|
Packit Service |
5956c7 |
|
|
Packit Service |
5956c7 |
if (a1->s_addr == a2->s_addr)
|
|
Packit Service |
5956c7 |
return true;
|
|
Packit Service |
5956c7 |
}
|
|
Packit Service |
5956c7 |
|
|
Packit Service |
5956c7 |
return false;
|
|
Packit Service |
5956c7 |
}
|
|
Packit Service |
5956c7 |
|
|
Packit Service |
5956c7 |
static inline uint16_t csum_incremental_update32(const uint16_t old_csum, const uint32_t old_val, const uint32_t new_val)
|
|
Packit Service |
5956c7 |
{
|
|
Packit Service |
5956c7 |
/* This technique for incremental IP checksum update is described in RFC1624,
|
|
Packit Service |
5956c7 |
* along with accompanying errata */
|
|
Packit Service |
5956c7 |
|
|
Packit Service |
5956c7 |
if (old_val == new_val)
|
|
Packit Service |
5956c7 |
return old_csum;
|
|
Packit Service |
5956c7 |
|
|
Packit Service |
5956c7 |
uint32_t acc = (~old_csum & 0xffff) + (~(old_val >> 16 ) & 0xffff) + (~old_val & 0xffff);
|
|
Packit Service |
5956c7 |
|
|
Packit Service |
5956c7 |
acc += (new_val >> 16) + (new_val & 0xffff);
|
|
Packit Service |
5956c7 |
|
|
Packit Service |
5956c7 |
/* finally compute vrrp checksum */
|
|
Packit Service |
5956c7 |
acc = (acc & 0xffff) + (acc >> 16);
|
|
Packit Service |
5956c7 |
acc += acc >> 16;
|
|
Packit Service |
5956c7 |
|
|
Packit Service |
5956c7 |
return ~acc & 0xffff;
|
|
Packit Service |
5956c7 |
}
|
|
Packit Service |
5956c7 |
|
|
Packit Service |
5956c7 |
static inline uint16_t csum_incremental_update16(const uint16_t old_csum, const uint16_t old_val, const uint16_t new_val)
|
|
Packit Service |
5956c7 |
{
|
|
Packit Service |
5956c7 |
/* This technique for incremental IP checksum update is described in RFC1624,
|
|
Packit Service |
5956c7 |
* along with accompanying errata */
|
|
Packit Service |
5956c7 |
|
|
Packit Service |
5956c7 |
if (old_val == new_val)
|
|
Packit Service |
5956c7 |
return old_csum;
|
|
Packit Service |
5956c7 |
|
|
Packit Service |
5956c7 |
uint32_t acc = (~old_csum & 0xffff) + (~old_val & 0xffff);
|
|
Packit Service |
5956c7 |
|
|
Packit Service |
5956c7 |
acc += new_val;
|
|
Packit Service |
5956c7 |
|
|
Packit Service |
5956c7 |
/* finally compute vrrp checksum */
|
|
Packit Service |
5956c7 |
acc = (acc & 0xffff) + (acc >> 16);
|
|
Packit Service |
5956c7 |
acc += acc >> 16;
|
|
Packit Service |
5956c7 |
|
|
Packit Service |
5956c7 |
return ~acc & 0xffff;
|
|
Packit Service |
5956c7 |
}
|
|
Packit Service |
5956c7 |
|
|
Packit Service |
5956c7 |
/* global vars exported */
|
|
Packit Service |
5956c7 |
extern unsigned long debug;
|
|
Packit Service |
5956c7 |
#ifdef _WITH_PERF_
|
|
Packit Service |
5956c7 |
extern perf_t perf_run;
|
|
Packit Service |
5956c7 |
#endif
|
|
Packit Service |
5956c7 |
|
|
Packit Service |
5956c7 |
/* Prototypes defs */
|
|
Packit Service |
5956c7 |
extern void dump_buffer(char *, size_t, FILE *, int);
|
|
Packit Service |
5956c7 |
#ifdef _WITH_STACKTRACE_
|
|
Packit Service |
5956c7 |
extern void write_stacktrace(const char *, const char *);
|
|
Packit Service |
5956c7 |
#endif
|
|
Packit Service |
5956c7 |
extern char *make_file_name(const char *, const char *, const char *, const char *);
|
|
Packit Service |
5956c7 |
#ifdef _WITH_PERF_
|
|
Packit Service |
5956c7 |
extern void run_perf(const char *, const char *, const char *);
|
|
Packit Service |
5956c7 |
#endif
|
|
Packit Service |
5956c7 |
extern uint16_t in_csum(const uint16_t *, size_t, uint32_t, uint32_t *);
|
|
Packit Service |
5956c7 |
extern char *inet_ntop2(uint32_t);
|
|
Packit Service |
5956c7 |
extern bool inet_stor(const char *, uint32_t *);
|
|
Packit Service |
5956c7 |
extern int domain_stosockaddr(const char *, const char *, struct sockaddr_storage *);
|
|
Packit Service |
5956c7 |
extern int inet_stosockaddr(char *, const char *, struct sockaddr_storage *);
|
|
Packit Service |
5956c7 |
extern void inet_ip4tosockaddr(struct in_addr *, struct sockaddr_storage *);
|
|
Packit Service |
5956c7 |
extern void inet_ip6tosockaddr(struct in6_addr *, struct sockaddr_storage *);
|
|
Packit Service |
5956c7 |
extern char *inet_sockaddrtos(struct sockaddr_storage *);
|
|
Packit Service |
5956c7 |
extern char *inet_sockaddrtopair(struct sockaddr_storage *);
|
|
Packit Service |
5956c7 |
extern char *inet_sockaddrtotrio(struct sockaddr_storage *, uint16_t);
|
|
Packit Service |
5956c7 |
extern uint16_t inet_sockaddrport(struct sockaddr_storage *);
|
|
Packit Service |
5956c7 |
extern uint32_t inet_sockaddrip4(struct sockaddr_storage *);
|
|
Packit Service |
5956c7 |
extern int inet_sockaddrip6(struct sockaddr_storage *, struct in6_addr *);
|
|
Packit Service |
5956c7 |
extern int inet_inaddrcmp(int, const void *, const void *);
|
|
Packit Service |
5956c7 |
extern int inet_sockaddrcmp(const struct sockaddr_storage *, const struct sockaddr_storage *);
|
|
Packit Service |
5956c7 |
extern char *get_local_name(void);
|
|
Packit Service |
5956c7 |
extern bool string_equal(const char *, const char *);
|
|
Packit Service |
5956c7 |
extern FILE *fopen_safe(const char *, const char *);
|
|
Packit Service |
5956c7 |
extern void set_std_fd(bool);
|
|
Packit Service |
5956c7 |
extern void close_std_fd(void);
|
|
Packit Service |
5956c7 |
#if !defined _HAVE_LIBIPTC_ || defined _LIBIPTC_DYNAMIC_
|
|
Packit Service |
5956c7 |
extern int fork_exec(char **);
|
|
Packit Service |
5956c7 |
#endif
|
|
Packit Service |
5956c7 |
#if defined _WITH_VRRP_ || defined _WITH_BFD_
|
|
Packit Service |
5956c7 |
extern int open_pipe(int [2]);
|
|
Packit Service |
5956c7 |
#endif
|
|
Packit Service |
5956c7 |
extern int memcmp_constant_time(const void *, const void *, size_t);
|
|
Packit Service |
5956c7 |
|
|
Packit Service |
5956c7 |
#endif
|