David Martin has proposed merging lp:~martin-lp/hipl/hipfwconf into lp:hipl. Requested reviews: Miika Komu (miika-iki) For more details, see: https://code.launchpad.net/~martin-lp/hipl/hipfwconf/+merge/80830 This branch introduces changes to get the currently active connection from the firewall. This is a resubmitted merge proposal: instead of using a separate binary option 1 of the previous discussion is implemented: > 1) add an extra keyword to the hipconf command line: hipconf (daemon | > firewall) COMMAND Summed up changes since the last proposal (revision 6116ff.): Keywords to address hipd / hipfw are daemon and firewall and defined in lib/core/conf.h. The hipconf help print has been updated. Config file syntax does not have to be changed as only hipd parses configs via hipconf and the daemon keyword is hardcoded. >From what I've tested everything works as before. I do not know all hipconf >options or how to apply them so I did not test them all. Please have a look if everything seems right. -- https://code.launchpad.net/~martin-lp/hipl/hipfwconf/+merge/80830 Your team HIPL core team is subscribed to branch lp:hipl.
=== modified file 'Makefile.am' --- Makefile.am 2011-10-17 18:14:10 +0000 +++ Makefile.am 2011-10-31 18:21:26 +0000 @@ -90,8 +90,8 @@ firewall/port_bindings.c test_hc_performance_SOURCES = test/hc_performance.c -tools_hipconf_SOURCES = tools/hipconf.c -tools_pisacert_SOURCES = tools/pisacert.c +tools_hipconf_SOURCES = tools/hipconf.c +tools_pisacert_SOURCES = tools/pisacert.c hipd_hipd_sources = hipd/accessor.c \ hipd/cert.c \ === modified file 'firewall/conntrack.c' --- firewall/conntrack.c 2011-10-25 21:14:16 +0000 +++ firewall/conntrack.c 2011-10-31 18:21:26 +0000 @@ -2244,3 +2244,56 @@ remove_connection(conn_list->data); } } + +/** + * Prepare given message with host association info from the tracked connections. + * + * @param msg The message where the info is written. + * @return 0 on success + * -1 on error + */ +int hip_fw_handle_get_ha_info(struct hip_common *msg) +{ + struct hip_hadb_user_info_state hid = { { { { 0 } } } }; + struct slist *iter_conn; + struct connection *conn; + struct hip_data *data; + + if (!msg) { + HIP_ERROR("Missing message parameter.\n"); + return -1; + } + + if (conn_list == NULL) { + HIP_DEBUG("No tracked connections to return.\n"); + return 0; + } + + hip_msg_init(msg); + if (hip_build_user_hdr(msg, HIP_MSG_GET_HA_INFO, 0) < 0) { + HIP_ERROR("Failed to build GET_HA_INFO message header.\n"); + return -1; + } + + iter_conn = conn_list; + while (iter_conn) { + conn = iter_conn->data; + data = conn->original.hip_tuple->data; + + // build HA_INFO with info from connection initiator + hid.state = conn->state; + ipv6_addr_copy(&hid.hit_our, &data->src_hit); + ipv6_addr_copy(&hid.hit_peer, &data->dst_hit); + hid.nat_udp_port_local = conn->original.src_port; + hid.nat_udp_port_peer = conn->original.dst_port; + + if (hip_build_param_contents(msg, &hid, HIP_PARAM_HA_INFO, sizeof(hid)) < 0) { + HIP_ERROR("Failed to build initiator HA_INFO parameter.\n"); + return -1; + } + + iter_conn = iter_conn->next; + } + + return 0; +} === modified file 'firewall/conntrack.h' --- firewall/conntrack.h 2011-07-18 16:31:37 +0000 +++ firewall/conntrack.h 2011-10-31 18:21:26 +0000 @@ -63,4 +63,6 @@ void hip_fw_conntrack_periodic_cleanup(void); void hip_fw_uninit_conntrack(void); +int hip_fw_handle_get_ha_info(struct hip_common *msg); + #endif /* HIP_FIREWALL_CONNTRACK_H */ === modified file 'firewall/firewall.c' --- firewall/firewall.c 2011-10-30 11:41:51 +0000 +++ firewall/firewall.c 2011-10-31 18:21:26 +0000 @@ -1672,7 +1672,7 @@ n = recvfrom(hip_fw_async_sock, msg, sizeof(struct hip_common), MSG_PEEK, (struct sockaddr *) &sock_addr, &alen); if (n < 0) { - HIP_ERROR("Error receiving message header from daemon.\n"); + HIP_ERROR("Error receiving message header.\n"); return -1; } @@ -1701,24 +1701,13 @@ (struct sockaddr *) &sock_addr, &alen); if (n < 0) { - HIP_ERROR("Error receiving message parameters from daemon.\n"); + HIP_ERROR("Error receiving message parameters.\n"); return -1; } HIP_ASSERT(n == len); - if (ntohs(sock_addr.sin6_port) != HIP_DAEMON_LOCAL_PORT) { - int type = hip_get_msg_type(msg); - if (type == HIP_MSG_FW_BEX_DONE) { - HIP_DEBUG("HIP_MSG_FW_BEX_DONE\n"); - HIP_DEBUG("%d == %d\n", ntohs(sock_addr.sin6_port), - HIP_DAEMON_LOCAL_PORT); - } - HIP_DEBUG("Drop, message not from hipd\n"); - return -1; - } - - if (hip_handle_msg(msg) < 0) { + if (hip_handle_msg(msg, (struct sockaddr *) &sock_addr) < 0) { HIP_ERROR("Error handling message\n"); return -1; } @@ -1847,8 +1836,6 @@ sock_addr.sin6_addr = in6addr_loopback; HIP_IFEL(bind(hip_fw_async_sock, (struct sockaddr *) &sock_addr, sizeof(sock_addr)), -1, "Bind on firewall socket addr failed. Give -k option to kill old hipfw\n"); - HIP_IFEL(hip_daemon_connect(hip_fw_async_sock), -1, - "connecting socket failed\n"); /* Starting hipfw does not always work when hipfw starts first -miika */ if (hip_userspace_ipsec || hip_lsi_support) { @@ -1944,7 +1931,7 @@ } if (FD_ISSET(hip_fw_async_sock, &read_fdset)) { - HIP_DEBUG("****** Received HIPD message ******\n"); + HIP_DEBUG("****** Received user message ******\n"); err = fw_handle_hipd_message(msg); } @@ -2009,3 +1996,31 @@ return &default_lsi; } + +/** + * Send a message via the firewall socket for asynchronous messages. + * Caller is responsible for setting up the message. + * + * @param msg The message to be sent. + * @param addr The destination address. + * + * @return 0 on success + * -1 on error + */ +int hip_fw_send_message(const struct hip_common *const msg, + const struct sockaddr *const addr) +{ + uint16_t len; + + if (msg == NULL || addr == NULL) { + HIP_ERROR("Empty message or address.\n"); + return -1; + } + + len = hip_get_msg_total_len(msg); + if (sendto(hip_fw_async_sock, msg, len, 0, addr, hip_sockaddr_len(addr)) != len) { + return -1; + } + + return 0; +} === modified file 'firewall/firewall.h' --- firewall/firewall.h 2011-04-05 16:44:22 +0000 +++ firewall/firewall.h 2011-10-31 18:21:26 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 Aalto University and RWTH Aachen University. + * Copyright (c) 2010-2011 Aalto University and RWTH Aachen University. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -55,5 +55,7 @@ void hip_fw_uninit_esp_relay(void); hip_hit_t *hip_fw_get_default_hit(void); hip_lsi_t *hip_fw_get_default_lsi(void); +int hip_fw_send_message(const struct hip_common *const msg, + const struct sockaddr *const addr); #endif /* HIP_FIREWALL_FIREWALL_H */ === modified file 'firewall/firewall_control.c' --- firewall/firewall_control.c 2011-10-25 21:14:16 +0000 +++ firewall/firewall_control.c 2011-10-31 18:21:26 +0000 @@ -38,10 +38,12 @@ #include <string.h> #include <netinet/in.h> +#include "conntrack.h" #include "lib/core/builder.h" #include "lib/core/debug.h" #include "lib/core/ife.h" #include "lib/core/message.h" +#include "lib/core/prefix.h" #include "lib/core/protodefs.h" #include "cache.h" #include "firewall.h" @@ -91,12 +93,12 @@ } /** - * distribute a message from hipd to the respective extension handler + * distribute a user message to the respective extension handler * * @param msg pointer to the received user message * @return 0 on success, else -1 */ -int hip_handle_msg(struct hip_common *msg) +int hip_handle_msg(struct hip_common *msg, struct sockaddr *addr) { int type, err = 0; struct hip_common *msg_out = NULL; @@ -150,12 +152,36 @@ HIP_IFEL(hip_send_recv_daemon_info(msg_out, 1, hip_fw_sock), -1, "Couldn't notify daemon of firewall presence\n"); break; + case HIP_MSG_GET_HA_INFO: + HIP_IFEL(hip_fw_handle_get_ha_info(msg), -1, + "Could not handle GET_HA message.\n"); + HIP_IFEL(hip_fw_send_message(msg, addr), -1, + "Could not send HA reply.\n"); + break; default: HIP_ERROR("Unhandled message type %d\n", type); err = -1; break; } + out_err: + if (hip_get_msg_response(msg)) { + HIP_DEBUG("Send response\n"); + if (err) { + hip_hdr msg_type = hip_get_msg_type(msg); + hip_msg_init(msg); + hip_build_user_hdr(msg, msg_type, 0); + hip_set_msg_err(msg, 1); + } + HIP_DEBUG("Sending message (type=%d) response\n", + hip_get_msg_type(msg)); + if (hip_fw_send_message(msg, addr) == -1) { + err = -1; + } else { + HIP_DEBUG("Response sent ok\n"); + } + } + free(msg_out); return err; } === modified file 'firewall/firewall_control.h' --- firewall/firewall_control.h 2010-10-15 15:29:14 +0000 +++ firewall/firewall_control.h 2011-10-31 18:21:26 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 Aalto University and RWTH Aachen University. + * Copyright (c) 2010-2011 Aalto University and RWTH Aachen University. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -28,6 +28,6 @@ #include "lib/core/protodefs.h" -int hip_handle_msg(struct hip_common *msg); +int hip_handle_msg(struct hip_common *msg, struct sockaddr *addr); #endif /* HIP_FIREWALL_FIREWALL_CONTROL_H */ === modified file 'lib/core/conf.c' --- lib/core/conf.c 2011-10-31 17:38:04 +0000 +++ lib/core/conf.c 2011-10-31 18:21:26 +0000 @@ -181,6 +181,11 @@ /* #define TYPE_RELAY 22 */ /** + * The daemon process to be configured by the conf command. + */ +enum daemon_name daemon_name; + +/** * A help string containing the usage of @c hipconf and also * @c HIPL_SYSCONFDIR/hipd_config. * @@ -226,6 +231,47 @@ ; /** + * A help string containing the usage of @c hipfwconf. + * + * @note If you added a new action, do not forget to add a brief usage below + * for the action. + */ +const char *hipfwconf_usage = "get ha <hit> | all\n"; + +/** + * Send a message to hipd or hipfw and optionally receive an answer. + * + * @param msg The message to be sent. The respective answer will be stored + * here as well. + * @param send_only 1 if no response from hipd should be requested. + * 0 if it should block until a response from hipd is received. + * This option has no effect when sending messages to hipfw. + * + * @return 0 on success + * -1 on error + */ +static int send_receive_message(struct hip_common *msg, + const int send_only) +{ + if (daemon_name == HIP_DAEMON) { + if (hip_send_recv_daemon_info(msg, send_only, 0)) { + HIP_ERROR("Failed to send user message to the HIP daemon.\n"); + return -1; + } + } else if (daemon_name == HIP_FIREWALL) { + if (hip_send_recv_firewall_info(msg)) { + HIP_ERROR("Failed to send user message to the HIP firewall.\n"); + return -1; + } + } else { + HIP_ERROR("Destination daemon process unknown.\n"); + return -1; + } + + return 0; +} + +/** * Query hipd for the HITs of the local host * * @param msg input/output message for the query/response for hipd @@ -510,6 +556,25 @@ /* Non-static functions -> global scope */ /** + * Map daemon / firewall keyboard to its respective enum. + * + * @param argv an array of strings (command line args to hipconf) + * @return HIP_DAEMON in case of hipd keyword + * HIP_FIREWALL in case of hipfw keyword + * -1 else + */ +static int conf_get_process(const char *argv[]) +{ + if (!strcmp(HIPCONF_HIPD_KEYWORD, argv[1])) { + return HIP_DAEMON; + } else if (!strcmp(HIPCONF_HIPFW_KEYWORD, argv[1])) { + return HIP_FIREWALL; + } + + return -1; +} + +/** * Map a symbolic hipconf action (=add/del) into a number * * @param argv an array of strings (command line args to hipconf) @@ -526,61 +591,61 @@ { int ret = -1; - if (!strcmp("add", argv[1])) { + if (!strcmp("add", argv[2])) { ret = ACTION_ADD; - } else if (!strcmp("del", argv[1])) { + } else if (!strcmp("del", argv[2])) { ret = ACTION_DEL; - } else if (!strcmp("new", argv[1])) { + } else if (!strcmp("new", argv[2])) { ret = ACTION_NEW; - } else if (!strcmp("get", argv[1])) { + } else if (!strcmp("get", argv[2])) { ret = ACTION_GET; - } else if (!strcmp("set", argv[1])) { + } else if (!strcmp("set", argv[2])) { ret = ACTION_SET; - } else if (!strcmp("inc", argv[1])) { + } else if (!strcmp("inc", argv[2])) { ret = ACTION_INC; - } else if (!strcmp("dec", argv[1])) { + } else if (!strcmp("dec", argv[2])) { ret = ACTION_DEC; - } else if (!strcmp("rst", argv[1])) { + } else if (!strcmp("rst", argv[2])) { ret = ACTION_RST; - } else if (!strcmp("run", argv[1])) { + } else if (!strcmp("run", argv[2])) { ret = ACTION_RUN; - } else if (!strcmp("load", argv[1])) { + } else if (!strcmp("load", argv[2])) { ret = ACTION_LOAD; - } else if (!strcmp("heartbeat", argv[1])) { + } else if (!strcmp("heartbeat", argv[2])) { ret = ACTION_HEARTBEAT; - } else if (!strcmp("locator", argv[1])) { + } else if (!strcmp("locator", argv[2])) { ret = ACTION_LOCATOR; - } else if (!strcmp("debug", argv[1])) { + } else if (!strcmp("debug", argv[2])) { ret = ACTION_DEBUG; - } else if (!strcmp("transform", argv[1])) { + } else if (!strcmp("transform", argv[2])) { ret = ACTION_TRANSORDER; - } else if (!strcmp("reinit", argv[1])) { + } else if (!strcmp("reinit", argv[2])) { ret = ACTION_REINIT; - } else if (!strcmp("manual-update", argv[1])) { + } else if (!strcmp("manual-update", argv[2])) { ret = ACTION_MANUAL_UPDATE; - } else if (!strcmp("hit-to-lsi", argv[1])) { + } else if (!strcmp("hit-to-lsi", argv[2])) { ret = ACTION_HIT_TO_LSI; - } else if (!strcmp("nsupdate", argv[1])) { + } else if (!strcmp("nsupdate", argv[2])) { ret = ACTION_NSUPDATE; - } else if (!strcmp("hit-to-ip-set", argv[1])) { + } else if (!strcmp("hit-to-ip-set", argv[2])) { ret = ACTION_HIT_TO_IP_SET; - } else if (!strcmp("hit-to-ip", argv[1])) { + } else if (!strcmp("hit-to-ip", argv[2])) { ret = ACTION_HIT_TO_IP; - } else if (!strcmp("shotgun", argv[1])) { + } else if (!strcmp("shotgun", argv[2])) { ret = ACTION_SHOTGUN; - } else if (!strcmp("lsi-to-hit", argv[1])) { + } else if (!strcmp("lsi-to-hit", argv[2])) { ret = ACTION_LSI_TO_HIT; - } else if (!strcmp("nat", argv[1])) { - if (!strcmp("port", argv[2])) { - if (!strcmp("local", argv[3])) { + } else if (!strcmp("nat", argv[2])) { + if (!strcmp("port", argv[3])) { + if (!strcmp("local", argv[4])) { ret = ACTION_NAT_LOCAL_PORT; - } else if (!strcmp("peer", argv[3])) { + } else if (!strcmp("peer", argv[4])) { ret = ACTION_NAT_PEER_PORT; } } else { ret = ACTION_NAT; } - } else if (!strcmp("broadcast", argv[1])) { + } else if (!strcmp("broadcast", argv[2])) { ret = ACTION_BROADCAST; } @@ -670,45 +735,45 @@ ret = TYPE_HA; } else if (!strcmp("shotgun", text)) { ret = TYPE_SHOTGUN; - } else if ((!strcmp("all", text)) && (strcmp("rst", argv[1]) == 0)) { - ret = TYPE_RST; - } else if ((!strcmp("peer_hit", text)) && (strcmp("rst", argv[1]) == 0)) { - ret = TYPE_RST; - } else if (strcmp("nat", argv[1]) == 0) { - if (argv[2] && strcmp("port", argv[2]) == 0) { - if (argv[3] && strcmp("local", argv[3]) == 0) { + } else if ((!strcmp("all", text)) && (strcmp("rst", argv[2]) == 0)) { + ret = TYPE_RST; + } else if ((!strcmp("peer_hit", text)) && (strcmp("rst", argv[2]) == 0)) { + ret = TYPE_RST; + } else if (strcmp("nat", argv[2]) == 0) { + if (argv[3] && strcmp("port", argv[3]) == 0) { + if (argv[4] && strcmp("local", argv[4]) == 0) { ret = TYPE_NAT_LOCAL_PORT; - } else if (argv[3] && strcmp("peer", argv[3]) == 0) { + } else if (argv[4] && strcmp("peer", argv[4]) == 0) { ret = TYPE_NAT_PEER_PORT; } } else { ret = TYPE_NAT; } - } else if (strcmp("locator", argv[1]) == 0) { + } else if (strcmp("locator", argv[2]) == 0) { ret = TYPE_LOCATOR; } else if (!strcmp("debug", text)) { ret = TYPE_DEBUG; } else if (!strcmp("order", text)) { ret = TYPE_ORDER; - } else if (strcmp("heartbeat", argv[1]) == 0) { + } else if (strcmp("heartbeat", argv[2]) == 0) { ret = TYPE_HEARTBEAT; } else if (!strcmp("ttl", text)) { ret = TYPE_TTL; } else if (!strcmp("config", text)) { ret = TYPE_CONFIG; - } else if (strcmp("manual-update", argv[1]) == 0) { + } else if (strcmp("manual-update", argv[2]) == 0) { ret = TYPE_MANUAL_UPDATE; - } else if (strcmp("hit-to-lsi", argv[1]) == 0) { + } else if (strcmp("hit-to-lsi", argv[2]) == 0) { ret = TYPE_HIT_TO_LSI; - } else if (strcmp("nsupdate", argv[1]) == 0) { + } else if (strcmp("nsupdate", argv[2]) == 0) { ret = TYPE_NSUPDATE; - } else if (strcmp("hit-to-ip-set", argv[1]) == 0) { + } else if (strcmp("hit-to-ip-set", argv[2]) == 0) { ret = TYPE_HIT_TO_IP_SET; - } else if (strcmp("hit-to-ip", argv[1]) == 0) { + } else if (strcmp("hit-to-ip", argv[2]) == 0) { ret = TYPE_HIT_TO_IP; - } else if (strcmp("lsi-to-hit", argv[1]) == 0) { + } else if (strcmp("lsi-to-hit", argv[2]) == 0) { ret = TYPE_LSI_TO_HIT; - } else if (strcmp("broadcast", argv[1]) == 0) { + } else if (strcmp("broadcast", argv[2]) == 0) { ret = TYPE_BROADCAST; } else { HIP_DEBUG("ERROR: NO MATCHES FOUND \n"); @@ -725,7 +790,7 @@ * here in the switch(action) block. * @param action integer value for an action * @return an index for argv[], which indicates the type argument. - * Usually either 1 or 2. + * Usually either 2 or 3. */ static int conf_get_type_arg(int action) { @@ -753,15 +818,15 @@ case ACTION_HIT_TO_IP: case ACTION_HIT_TO_IP_SET: case ACTION_BROADCAST: + type_arg = 3; + break; + case ACTION_MANUAL_UPDATE: + case ACTION_HIT_TO_LSI: + case ACTION_LSI_TO_HIT: + case ACTION_DEBUG: + case ACTION_SHOTGUN: type_arg = 2; break; - case ACTION_MANUAL_UPDATE: - case ACTION_HIT_TO_LSI: - case ACTION_LSI_TO_HIT: - case ACTION_DEBUG: - case ACTION_SHOTGUN: - type_arg = 1; - break; default: break; } @@ -2042,10 +2107,10 @@ HIP_IFEL(optc > 1, -1, "Too many arguments\n"); HIP_IFEL(hip_build_user_hdr(msg, HIP_MSG_GET_HA_INFO, 0), -1, - "Building of daemon header failed\n"); + "Building of user msg header failed\n"); - HIP_IFEL(hip_send_recv_daemon_info(msg, send_only, 0), -1, - "send recv daemon info\n"); + HIP_IFEL(send_receive_message(msg, send_only), -1, + "send recv info\n"); while ((current_param = hip_get_next_param(msg, current_param))) { ha = hip_get_param_contents_direct(current_param); @@ -2313,8 +2378,9 @@ *comment = '\0'; } - /* prefix the contents of the line with" hipconf" */ - res_len = sprintf(str, "hipconf %s", c); + /* prefix the contents of the line with" hipconf HIPCONF_HIPD_KEYWORD" + * Only hipd parses config files as hipconf commands, hardcode it as target */ + res_len = sprintf(str, "hipconf %s %s", HIPCONF_HIPD_KEYWORD, c); if (str[res_len] == '\n') { str[res_len] = '\0'; } @@ -2327,7 +2393,6 @@ args[i++] = token; token = strtok(NULL, " \t"); } - err = hip_do_hipconf(i, args, 1); if (err) { HIP_ERROR("Error on the following line: %s\n", line); @@ -2440,6 +2505,7 @@ * * @param argc the number of arguments * @param argv the arguments + * @param daemon_process HIP_DAEMON for messages to hipd, HIP_FIREWALL for hipfw * @param send_only 1 if no response from hipd should be requrested, or 0 if * should block for a response from hipd * @return zero for success and negative on error @@ -2451,24 +2517,29 @@ struct hip_common *msg = NULL; /* Check that we have at least one command line argument. */ - if (argc < 2) { - HIP_ERROR("Invalid arguments.\n\n%s usage:\n%s\n", - argv[0], hipconf_usage); + if (argc < 3) { + HIP_ERROR("Invalid arguments.\nUsage: %s %s | %s <command>\n\n" + "HIP daemon commands:\n%s\n\nHIP firewall commands:\n%s\n", + argv[0], HIPCONF_HIPD_KEYWORD, HIPCONF_HIPFW_KEYWORD, + hipconf_usage, hipfwconf_usage); return -1; } + /* set context for this conf command */ + daemon_name = conf_get_process(argv); + /* Get a numeric value representing the action. */ action = conf_get_action(argv); if (action == -1) { - HIP_ERROR("Invalid action argument '%s'\n", argv[1]); + HIP_ERROR("Invalid action argument '%s'\n", argv[2]); return -1; } /* Check that we have at least the minimum number of arguments * for the given action. */ - if (argc < conf_check_action_argc(action) + 2) { - HIP_ERROR("Not enough arguments given for the action '%s'\n", argv[1]); + if (argc < conf_check_action_argc(action) + 3) { + HIP_ERROR("Not enough arguments given for the action '%s'\n", argv[2]); return -1; } @@ -2496,14 +2567,14 @@ /* Call handler function from the handler function pointer * array at index "type" with given commandline arguments. * The functions build a hip_common message. */ - if (argc == 3) { - err = (*action_handler[type])(msg, action, &argv[2], argc - 3, send_only); + if (argc == 4) { + err = (*action_handler[type])(msg, action, &argv[3], argc - 4, send_only); } else { - err = (*action_handler[type])(msg, action, &argv[3], argc - 3, send_only); + err = (*action_handler[type])(msg, action, &argv[4], argc - 4, send_only); } if (err != 0) { - HIP_ERROR("Failed to send a message to the HIP daemon.\n"); + HIP_ERROR("Failed to send user message.\n"); goto out_err; } @@ -2512,9 +2583,7 @@ goto out_err; } - /* Send message to hipd */ - HIP_IFEL(hip_send_recv_daemon_info(msg, send_only, 0), -1, - "Failed to send user message to the HIP daemon.\n"); + send_receive_message(msg, send_only); HIP_INFO("User message was sent successfully to the HIP daemon.\n"); === modified file 'lib/core/conf.h' --- lib/core/conf.h 2011-08-15 14:11:56 +0000 +++ lib/core/conf.h 2011-10-31 18:21:26 +0000 @@ -54,6 +54,11 @@ #define ACTION_ADD 1 #define ACTION_NEW 3 +enum daemon_name { HIP_DAEMON, HIP_FIREWALL }; +/* keywords used to identify hipd / hipfw as target of hipconf command */ +#define HIPCONF_HIPD_KEYWORD "daemon" +#define HIPCONF_HIPFW_KEYWORD "firewall" + int hip_handle_exec_app(int fork, int type, int argc, const char *const argv[]); int hip_do_hipconf(int argc, const char *argv[], int send_only); === modified file 'lib/core/message.c' --- lib/core/message.c 2011-10-25 21:44:47 +0000 +++ lib/core/message.c 2011-10-31 18:21:26 +0000 @@ -178,6 +178,30 @@ } /** + * Connect a socket to the loopback address of hipd or hipfw. + * + * @param hip_user_sock The socket to connect. + * @param port The port to connect. + * @return zero on success and negative on failure + * @note currently only SOCK_DGRAM and AF_INET6 are supported + */ +static int hip_connect(int hip_user_sock, int port) +{ + struct sockaddr_in6 addr = { 0 }; + + addr.sin6_family = AF_INET6; + addr.sin6_port = htons(port); + addr.sin6_addr = in6addr_loopback; + + if (connect(hip_user_sock, (struct sockaddr *) &addr, sizeof(addr))) { + HIP_ERROR("connection failed: %s\n", strerror(errno)); + return -1; + } + + return 0; +} + +/** * Connect a socket to the loop back address of hipd * * @param hip_user_sock The socket to connect. Currently only SOCK_DGRAM @@ -187,21 +211,7 @@ */ int hip_daemon_connect(int hip_user_sock) { - int err = 0; - struct sockaddr_in6 daemon_addr = { 0 }; - // We're using system call here add thus resetting errno. - errno = 0; - - daemon_addr.sin6_family = AF_INET6; - daemon_addr.sin6_port = htons(HIP_DAEMON_LOCAL_PORT); - daemon_addr.sin6_addr = in6addr_loopback; - - HIP_IFEL(connect(hip_user_sock, (struct sockaddr *) &daemon_addr, - sizeof(daemon_addr)), -1, "connection to daemon failed\n"); - -out_err: - - return err; + return hip_connect(hip_user_sock, HIP_DAEMON_LOCAL_PORT); } /** @@ -479,6 +489,83 @@ } /** + * A generic function to send messages to hipfw with subsequent reply. This will + * block the process until the hipfw sends the response or a predefined timeout + * is exceeded. + * + * @param msg An input/output parameter. As input, contains the + * message to be sent to hipfw. As output, hipfw response + * will be written here. + * @return zero on success and negative on failure. + * @note currently the only SOCK_DGRAM and AF_INET6 are supported + */ +int hip_send_recv_firewall_info(struct hip_common *const msg) +{ + int tmp_sock = 0, len = 0, n = 0, err = 0; + uint8_t msg_type_old, msg_type_new; + struct sockaddr_in6 dst_addr = { 0 }; + + HIP_ASSERT(msg); + const uint16_t msg_length = hip_get_msg_total_len(msg); + + if ((tmp_sock = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { + HIP_ERROR("failed to open new socket: %s\n", strerror(errno)); + return -1; + } + + dst_addr.sin6_family = AF_INET6; + dst_addr.sin6_addr = in6addr_loopback; + + HIP_IFEL(daemon_bind_socket(tmp_sock, (struct sockaddr *) &dst_addr), + -1, "bind failed\n"); + HIP_IFEL(hip_connect(tmp_sock, HIP_FIREWALL_PORT), -1, "connect failed\n"); + + /* Require a response from hipd */ + hip_set_msg_response(msg, 1); + + msg_type_old = hip_get_msg_type(msg); + + HIP_DEBUG("Sending msg type %d\n", msg_type_old); + HIP_IFEL(send(tmp_sock, msg, msg_length, 0) < msg_length, -1, + "sending of user message failed: %s\n", strerror(errno)); + + HIP_DEBUG("sending of user message successful. Waiting for reply...\n"); + + HIP_IFEL((len = peek_recv_total_len(tmp_sock, 0, + HIP_DEFAULT_MSG_TIMEOUT)) < 0, + -1, "failed to receive firewall reply\n"); + + n = recv(tmp_sock, msg, len, 0); + + HIP_DEBUG("%d bytes received from HIP daemon\n", n); + + if (n == 0) { + HIP_INFO("The HIP firewall has performed an " \ + "orderly shutdown.\n"); + // Note. This is not an error condition, thus we return zero. + goto out_err; + } else if (n < (int) sizeof(struct hip_common)) { + HIP_ERROR("Could not receive message from firewall.\n"); + goto out_err; + } + + /* You have a message synchronization problem if you see this error. */ + msg_type_new = hip_get_msg_type(msg); + HIP_IFEL(msg_type_new != msg_type_old, -1, + "Message sync problem. Expected %d, got %d\n", + msg_type_old, msg_type_new); + + if (hip_get_msg_err(msg)) { + HIP_ERROR("HIP message contained an error.\n"); + err = -EHIP; + } + +out_err: + close(tmp_sock); + return err; +} + +/** * Read an interprocess (user) message * * @param sockfd a socket from where to read === modified file 'lib/core/message.h' --- lib/core/message.h 2011-08-15 14:11:56 +0000 +++ lib/core/message.h 2011-10-31 18:21:26 +0000 @@ -46,5 +46,6 @@ int hip_send_recv_daemon_info(struct hip_common *msg, int send_only, int opt_socket); +int hip_send_recv_firewall_info(struct hip_common *const msg); #endif /* HIP_LIB_CORE_MESSAGE_H */