/* * Copyright (c) 2010-2011, Red Hat, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND RED HAT, INC. DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL RED HAT, INC. BE LIABLE * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* * Author: Jan Friesse */ #include #include #include #include #include #include #include "addrfunc.h" #include "logging.h" #include "msg.h" #include "msgsend.h" #include "omping.h" #include "rsfunc.h" #include "util.h" /* * Send answer message. ucast_socket is socket used to send message, mcast_addr is used multicast * address, orig_msg is received query message with orig_msg_len, decoded is decoded message, * to is sockaddr_storage address of destination, ttl is set TTL and answer_type can specify what * type of response to send. * Function returns 0 on sucess, otherwise same error as rs_sendto or -4 if message cannot be * created (usually due to small message buffer) */ int ms_answer(int ucast_socket, const struct sockaddr_storage *mcast_addr, const char *orig_msg, size_t orig_msg_len, const struct msg_decoded *decoded, const struct sockaddr_storage *to, uint8_t ttl, enum ms_answer_type answer_type) { char addr_str[INET6_ADDRSTRLEN]; char new_msg[MAX_MSG_SIZE]; struct sockaddr_storage to_mcast; size_t new_msg_len; ssize_t sent; new_msg_len = msg_answer_create(orig_msg, orig_msg_len, new_msg, sizeof(new_msg), ttl, decoded->request_opt_server_tstamp); if (new_msg_len == 0) { return (-4); } if (answer_type == MS_ANSWER_UCAST || answer_type == MS_ANSWER_BOTH) { af_sa_to_str(AF_CAST_SA(to), addr_str); DEBUG_PRINTF("Sending unicast answer msg to %s", addr_str); msg_update_server_tstamp(new_msg, new_msg_len); sent = rs_sendto(ucast_socket, new_msg, new_msg_len, to); if (sent < 0) { return (sent); } } if (answer_type == MS_ANSWER_MCAST || answer_type == MS_ANSWER_BOTH) { af_copy_addr(mcast_addr, to, 1, 2, &to_mcast); af_sa_to_str(AF_CAST_SA(&to_mcast), addr_str); DEBUG_PRINTF("Sending multicast answer msg to %s", addr_str); msg_update_server_tstamp(new_msg, new_msg_len); sent = rs_sendto(ucast_socket, new_msg, new_msg_len, &to_mcast); if (sent < 0) { return (sent); } } return (0); } /* * Send init message. ucast_socket is socket used to send message, remote_addr is address of host * to send message, mcast_addr is used multicast address, client_id is client id string with * CLIENTID_LEN length, req_si should be non 0 if server information request is required. * Function returns 0 on success, otherwise same error as rs_sendto or -4 if message cannot be * created (usually due to small message buffer) */ int ms_init(int ucast_socket, const struct sockaddr_storage *remote_addr, const struct sockaddr_storage *mcast_addr, const char *client_id, int req_si) { char addr_str[INET6_ADDRSTRLEN]; char msg[MAX_MSG_SIZE]; size_t msg_len; ssize_t sent; af_sa_to_str(AF_CAST_SA(remote_addr), addr_str); DEBUG_PRINTF("Sending init msg to %s", addr_str); msg_len = msg_init_create(msg, sizeof(msg), req_si, mcast_addr, client_id, CLIENTID_LEN); if (msg_len == 0) { return (-4); } sent = rs_sendto(ucast_socket, msg, msg_len, remote_addr); return (sent); } /* * Send query message. ucast_socket is socket used to send message, remote_addr is address of host * to send message, mcast_addr is used multicast address, client_id is client id string with * CLIENTID_LEN length, ses_id is Session ID string with ses_id_len length. seq_num is sequential * number to set in packet. * Function returns 0 on success, otherwise same error as rs_sendto or -4 if message cannot be * created (usually due to small message buffer) */ int ms_query(int ucast_socket, const struct sockaddr_storage *remote_addr, const struct sockaddr_storage *mcast_addr, uint32_t seq_num, const char *client_id, const char *ses_id, size_t ses_id_len) { char addr_str[INET6_ADDRSTRLEN]; char msg[MAX_MSG_SIZE]; size_t msg_len; ssize_t sent; af_sa_to_str(AF_CAST_SA(remote_addr), addr_str); DEBUG_PRINTF("Sending query msg to %s", addr_str); msg_len = msg_query_create(msg, sizeof(msg), mcast_addr, seq_num, 0, client_id, CLIENTID_LEN, ses_id, SESSIONID_LEN); if (msg_len == 0) { return (-4); } sent = rs_sendto(ucast_socket, msg, msg_len, remote_addr); return (sent); } /* * Send response message. ucast_socket is socket used to send message, mcast_addr is used multicast * address, decoded is decoded message, to is sockaddr_storage address of destination, mcast_grp is * used to distinguish if add or not add mcast group tlv, similarly to mcast_prefix. session_id and * is session id string with session_id_len length. * Function returns 0 on sucess, otherwise same error as rs_sendto or -4 if message cannot be * created (usually due to small message buffer) */ int ms_response(int ucast_socket, const struct sockaddr_storage *mcast_addr, const struct msg_decoded *decoded, const struct sockaddr_storage *to, int mcast_grp, int mcast_prefix, const char *session_id, size_t session_id_len) { char addr_str[INET6_ADDRSTRLEN]; char msg[MAX_MSG_SIZE]; size_t msg_len; ssize_t sent; af_sa_to_str((struct sockaddr *)to, addr_str); DEBUG_PRINTF("Sending response msg to %s", addr_str); msg_len = msg_response_create(msg, sizeof(msg), decoded, mcast_grp, mcast_prefix, mcast_addr, session_id, session_id_len); if (msg_len == 0) { return (-4); } sent = rs_sendto(ucast_socket, msg, msg_len, to); return (sent); } /* * Send response message with stop meaning. It's just shortcut to ms_send_response where * parameters with same name has same meaning. Also returned values are same. */ int ms_stop(int ucast_socket, const struct sockaddr_storage *mcast_addr, const struct msg_decoded *decoded, const struct sockaddr_storage *to) { return (ms_response(ucast_socket, mcast_addr, decoded, to, 0,0, NULL, 0)); }