Blame msgsend.c

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 <stdlib.h>
Packit 61cb5a
Packit 61cb5a
#include "addrfunc.h"
Packit 61cb5a
#include "logging.h"
Packit 61cb5a
#include "msg.h"
Packit 61cb5a
#include "msgsend.h"
Packit 61cb5a
#include "omping.h"
Packit 61cb5a
#include "rsfunc.h"
Packit 61cb5a
#include "util.h"
Packit 61cb5a
Packit 61cb5a
/*
Packit 61cb5a
 * Send answer message. ucast_socket is socket used to send message, mcast_addr is used multicast
Packit 61cb5a
 * address, orig_msg is received query message with orig_msg_len, decoded is decoded message,
Packit 61cb5a
 * to is sockaddr_storage address of destination, ttl is set TTL and answer_type can specify what
Packit 61cb5a
 * type of response to send.
Packit 61cb5a
 * Function returns 0 on sucess, otherwise same error as rs_sendto or -4 if message cannot be
Packit 61cb5a
 * created (usually due to small message buffer)
Packit 61cb5a
 */
Packit 61cb5a
int
Packit 61cb5a
ms_answer(int ucast_socket, const struct sockaddr_storage *mcast_addr, const char *orig_msg,
Packit 61cb5a
    size_t orig_msg_len, const struct msg_decoded *decoded, const struct sockaddr_storage *to,
Packit 61cb5a
    uint8_t ttl, enum ms_answer_type answer_type)
Packit 61cb5a
{
Packit 61cb5a
	char addr_str[INET6_ADDRSTRLEN];
Packit 61cb5a
	char new_msg[MAX_MSG_SIZE];
Packit 61cb5a
	struct sockaddr_storage to_mcast;
Packit 61cb5a
	size_t new_msg_len;
Packit 61cb5a
	ssize_t sent;
Packit 61cb5a
Packit 61cb5a
	new_msg_len = msg_answer_create(orig_msg, orig_msg_len, new_msg, sizeof(new_msg),
Packit 61cb5a
	    ttl, decoded->request_opt_server_tstamp);
Packit 61cb5a
Packit 61cb5a
	if (new_msg_len == 0) {
Packit 61cb5a
		return (-4);
Packit 61cb5a
	}
Packit 61cb5a
Packit 61cb5a
	if (answer_type == MS_ANSWER_UCAST || answer_type == MS_ANSWER_BOTH) {
Packit 61cb5a
		af_sa_to_str(AF_CAST_SA(to), addr_str);
Packit 61cb5a
		DEBUG_PRINTF("Sending unicast answer msg to %s", addr_str);
Packit 61cb5a
Packit 61cb5a
		msg_update_server_tstamp(new_msg, new_msg_len);
Packit 61cb5a
Packit 61cb5a
		sent = rs_sendto(ucast_socket, new_msg, new_msg_len, to);
Packit 61cb5a
Packit 61cb5a
		if (sent < 0) {
Packit 61cb5a
			return (sent);
Packit 61cb5a
		}
Packit 61cb5a
	}
Packit 61cb5a
Packit 61cb5a
	if (answer_type == MS_ANSWER_MCAST || answer_type == MS_ANSWER_BOTH) {
Packit 61cb5a
		af_copy_addr(mcast_addr, to, 1, 2, &to_mcast);
Packit 61cb5a
Packit 61cb5a
		af_sa_to_str(AF_CAST_SA(&to_mcast), addr_str);
Packit 61cb5a
		DEBUG_PRINTF("Sending multicast answer msg to %s", addr_str);
Packit 61cb5a
Packit 61cb5a
		msg_update_server_tstamp(new_msg, new_msg_len);
Packit 61cb5a
Packit 61cb5a
		sent = rs_sendto(ucast_socket, new_msg, new_msg_len, &to_mcast);
Packit 61cb5a
Packit 61cb5a
		if (sent < 0) {
Packit 61cb5a
			return (sent);
Packit 61cb5a
		}
Packit 61cb5a
	}
Packit 61cb5a
Packit 61cb5a
	return (0);
Packit 61cb5a
}
Packit 61cb5a
Packit 61cb5a
/*
Packit 61cb5a
 * Send init message. ucast_socket is socket used to send message, remote_addr is address of host
Packit 61cb5a
 * to send message, mcast_addr is used multicast address, client_id is client id string with
Packit 61cb5a
 * CLIENTID_LEN length, req_si should be non 0 if server information request is required.
Packit 61cb5a
 * Function returns 0 on success, otherwise same error as rs_sendto or -4 if message cannot be
Packit 61cb5a
 * created (usually due to small message buffer)
Packit 61cb5a
 */
Packit 61cb5a
int
Packit 61cb5a
ms_init(int ucast_socket, const struct sockaddr_storage *remote_addr,
Packit 61cb5a
    const struct sockaddr_storage *mcast_addr, const char *client_id, int req_si)
Packit 61cb5a
{
Packit 61cb5a
	char addr_str[INET6_ADDRSTRLEN];
Packit 61cb5a
	char msg[MAX_MSG_SIZE];
Packit 61cb5a
	size_t msg_len;
Packit 61cb5a
	ssize_t sent;
Packit 61cb5a
Packit 61cb5a
	af_sa_to_str(AF_CAST_SA(remote_addr), addr_str);
Packit 61cb5a
	DEBUG_PRINTF("Sending init msg to %s", addr_str);
Packit 61cb5a
Packit 61cb5a
	msg_len = msg_init_create(msg, sizeof(msg), req_si, mcast_addr, client_id, CLIENTID_LEN);
Packit 61cb5a
Packit 61cb5a
	if (msg_len == 0) {
Packit 61cb5a
		return (-4);
Packit 61cb5a
	}
Packit 61cb5a
Packit 61cb5a
	sent = rs_sendto(ucast_socket, msg, msg_len, remote_addr);
Packit 61cb5a
Packit 61cb5a
	return (sent);
Packit 61cb5a
}
Packit 61cb5a
Packit 61cb5a
/*
Packit 61cb5a
 * Send query message. ucast_socket is socket used to send message, remote_addr is address of host
Packit 61cb5a
 * to send message, mcast_addr is used multicast address, client_id is client id string with
Packit 61cb5a
 * CLIENTID_LEN length, ses_id is Session ID string with ses_id_len length. seq_num is sequential
Packit 61cb5a
 * number to set in packet.
Packit 61cb5a
 * Function returns 0 on success, otherwise same error as rs_sendto or -4 if message cannot be
Packit 61cb5a
 * created (usually due to small message buffer)
Packit 61cb5a
 */
Packit 61cb5a
int
Packit 61cb5a
ms_query(int ucast_socket, const struct sockaddr_storage *remote_addr,
Packit 61cb5a
    const struct sockaddr_storage *mcast_addr, uint32_t seq_num, const char *client_id,
Packit 61cb5a
    const char *ses_id, size_t ses_id_len)
Packit 61cb5a
{
Packit 61cb5a
	char addr_str[INET6_ADDRSTRLEN];
Packit 61cb5a
	char msg[MAX_MSG_SIZE];
Packit 61cb5a
	size_t msg_len;
Packit 61cb5a
	ssize_t sent;
Packit 61cb5a
Packit 61cb5a
	af_sa_to_str(AF_CAST_SA(remote_addr), addr_str);
Packit 61cb5a
	DEBUG_PRINTF("Sending query msg to %s", addr_str);
Packit 61cb5a
Packit 61cb5a
	msg_len = msg_query_create(msg, sizeof(msg), mcast_addr, seq_num, 0, client_id,
Packit 61cb5a
	    CLIENTID_LEN, ses_id, SESSIONID_LEN);
Packit 61cb5a
Packit 61cb5a
	if (msg_len == 0) {
Packit 61cb5a
		return (-4);
Packit 61cb5a
	}
Packit 61cb5a
Packit 61cb5a
	sent = rs_sendto(ucast_socket, msg, msg_len, remote_addr);
Packit 61cb5a
Packit 61cb5a
	return (sent);
Packit 61cb5a
}
Packit 61cb5a
Packit 61cb5a
/*
Packit 61cb5a
 * Send response message. ucast_socket is socket used to send message, mcast_addr is used multicast
Packit 61cb5a
 * address, decoded is decoded message, to is sockaddr_storage address of destination, mcast_grp is
Packit 61cb5a
 * used to distinguish if add or not add mcast group tlv, similarly to mcast_prefix. session_id and
Packit 61cb5a
 * is session id string with session_id_len length.
Packit 61cb5a
 * Function returns 0 on sucess, otherwise same error as rs_sendto or -4 if message cannot be
Packit 61cb5a
 * created (usually due to small message buffer)
Packit 61cb5a
 */
Packit 61cb5a
int
Packit 61cb5a
ms_response(int ucast_socket, const struct sockaddr_storage *mcast_addr,
Packit 61cb5a
    const struct msg_decoded *decoded, const struct sockaddr_storage *to, int mcast_grp,
Packit 61cb5a
    int mcast_prefix, const char *session_id, size_t session_id_len)
Packit 61cb5a
{
Packit 61cb5a
	char addr_str[INET6_ADDRSTRLEN];
Packit 61cb5a
	char msg[MAX_MSG_SIZE];
Packit 61cb5a
	size_t msg_len;
Packit 61cb5a
	ssize_t sent;
Packit 61cb5a
Packit 61cb5a
	af_sa_to_str((struct sockaddr *)to, addr_str);
Packit 61cb5a
	DEBUG_PRINTF("Sending response msg to %s", addr_str);
Packit 61cb5a
Packit 61cb5a
	msg_len = msg_response_create(msg, sizeof(msg), decoded, mcast_grp, mcast_prefix,
Packit 61cb5a
	    mcast_addr, session_id, session_id_len);
Packit 61cb5a
Packit 61cb5a
	if (msg_len == 0) {
Packit 61cb5a
		return (-4);
Packit 61cb5a
	}
Packit 61cb5a
Packit 61cb5a
	sent = rs_sendto(ucast_socket, msg, msg_len, to);
Packit 61cb5a
Packit 61cb5a
	return (sent);
Packit 61cb5a
}
Packit 61cb5a
Packit 61cb5a
/*
Packit 61cb5a
 * Send response message with stop meaning. It's just shortcut to ms_send_response where
Packit 61cb5a
 * parameters with same name has same meaning. Also returned values are same.
Packit 61cb5a
 */
Packit 61cb5a
int
Packit 61cb5a
ms_stop(int ucast_socket, const struct sockaddr_storage *mcast_addr,
Packit 61cb5a
    const struct msg_decoded *decoded, const struct sockaddr_storage *to)
Packit 61cb5a
{
Packit 61cb5a
	return (ms_response(ucast_socket, mcast_addr, decoded, to, 0,0, NULL, 0));
Packit 61cb5a
}