aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSree Harsha Totakura <totakura@in.tum.de>2013-04-02 15:36:31 +0000
committerSree Harsha Totakura <totakura@in.tum.de>2013-04-02 15:36:31 +0000
commitfcb359dc93bdf9c891edcfb965013e19c61981cf (patch)
treea19218dabc4b1a5c72fbb7f54f6d4c83daa1d889 /src
parent690ce06e4dff30f4e337b93d285d9ad090f5b03b (diff)
downloadgnunet-fcb359dc93bdf9c891edcfb965013e19c61981cf.tar.gz
gnunet-fcb359dc93bdf9c891edcfb965013e19c61981cf.zip
- manage services of peers (server)
Diffstat (limited to 'src')
-rw-r--r--src/testbed/Makefile.am1
-rw-r--r--src/testbed/gnunet-service-testbed.c279
2 files changed, 280 insertions, 0 deletions
diff --git a/src/testbed/Makefile.am b/src/testbed/Makefile.am
index 8b5cfbd9f..20056fba1 100644
--- a/src/testbed/Makefile.am
+++ b/src/testbed/Makefile.am
@@ -41,6 +41,7 @@ gnunet_service_testbed_LDADD = $(XLIB) \
41 $(top_builddir)/src/transport/libgnunettransport.la \ 41 $(top_builddir)/src/transport/libgnunettransport.la \
42 $(top_builddir)/src/testing/libgnunettesting.la \ 42 $(top_builddir)/src/testing/libgnunettesting.la \
43 $(top_builddir)/src/testbed/libgnunettestbed.la \ 43 $(top_builddir)/src/testbed/libgnunettestbed.la \
44 $(top_builddir)/src/arm/libgnunetarm.la \
44 $(LTLIBINTL) -lz 45 $(LTLIBINTL) -lz
45gnunet_service_testbed_DEPENDENCIES = \ 46gnunet_service_testbed_DEPENDENCIES = \
46 libgnunettestbed.la 47 libgnunettestbed.la
diff --git a/src/testbed/gnunet-service-testbed.c b/src/testbed/gnunet-service-testbed.c
index 81c17012d..e21879fab 100644
--- a/src/testbed/gnunet-service-testbed.c
+++ b/src/testbed/gnunet-service-testbed.c
@@ -1990,6 +1990,280 @@ handle_slave_get_config (void *cls, struct GNUNET_SERVER_Client *client,
1990 GNUNET_SERVER_receive_done (client, GNUNET_OK); 1990 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1991} 1991}
1992 1992
1993struct ManageServiceContext
1994{
1995
1996 struct ManageServiceContext *next;
1997
1998 struct ManageServiceContext *prev;
1999
2000 struct GNUNET_ARM_Handle *ah;
2001
2002 struct Peer *peer;
2003
2004 struct GNUNET_SERVER_Client *client;
2005
2006 uint64_t op_id;
2007
2008 uint8_t start;
2009
2010 uint8_t expired;
2011
2012};
2013
2014static struct ManageServiceContext *mctx_head;
2015
2016static struct ManageServiceContext *mctx_tail;
2017
2018static void
2019cleanup_mctx (struct ManageServiceContext *mctx)
2020{
2021 mctx->expired = GNUNET_YES;
2022 GNUNET_CONTAINER_DLL_remove (mctx_head, mctx_tail, mctx);
2023 GNUNET_SERVER_client_drop (mctx->client);
2024 GNUNET_ARM_disconnect_and_free (mctx->ah);
2025 GNUNET_assert (0 < mctx->peer->reference_cnt);
2026 mctx->peer->reference_cnt--;
2027 if ( (GNUNET_YES == mctx->peer->destroy_flag)
2028 && (0 == mctx->peer->reference_cnt) )
2029 GST_destroy_peer (mctx->peer);
2030 GNUNET_free (mctx);
2031}
2032
2033static void
2034free_mctxq ()
2035{
2036 while (NULL != mctx_head)
2037 cleanup_mctx (mctx_head);
2038}
2039
2040static const char *
2041arm_req_string (enum GNUNET_ARM_RequestStatus rs)
2042{
2043 switch (rs)
2044 {
2045 case GNUNET_ARM_REQUEST_SENT_OK:
2046 return _("Message was sent successfully");
2047 case GNUNET_ARM_REQUEST_CONFIGURATION_ERROR:
2048 return _("Misconfiguration (can't connect to the ARM service)");
2049 case GNUNET_ARM_REQUEST_DISCONNECTED:
2050 return _("We disconnected from ARM before we could send a request");
2051 case GNUNET_ARM_REQUEST_BUSY:
2052 return _("ARM API is busy");
2053 case GNUNET_ARM_REQUEST_TOO_LONG:
2054 return _("Request doesn't fit into a message");
2055 case GNUNET_ARM_REQUEST_TIMEOUT:
2056 return _("Request timed out");
2057 }
2058 return _("Unknown request status");
2059}
2060
2061static const char *
2062arm_ret_string (enum GNUNET_ARM_Result result)
2063{
2064 switch (result)
2065 {
2066 case GNUNET_ARM_RESULT_STOPPED:
2067 return _("%s is stopped");
2068 case GNUNET_ARM_RESULT_STARTING:
2069 return _("%s is starting");
2070 case GNUNET_ARM_RESULT_STOPPING:
2071 return _("%s is stopping");
2072 case GNUNET_ARM_RESULT_IS_STARTING_ALREADY:
2073 return _("%s is starting already");
2074 case GNUNET_ARM_RESULT_IS_STOPPING_ALREADY:
2075 return _("%s is stopping already");
2076 case GNUNET_ARM_RESULT_IS_STARTED_ALREADY:
2077 return _("%s is started already");
2078 case GNUNET_ARM_RESULT_IS_STOPPED_ALREADY:
2079 return _("%s is stopped already");
2080 case GNUNET_ARM_RESULT_IS_NOT_KNOWN:
2081 return _("%s service is not known to ARM");
2082 case GNUNET_ARM_RESULT_START_FAILED:
2083 return _("%s service failed to start");
2084 case GNUNET_ARM_RESULT_IN_SHUTDOWN:
2085 return _("%s service can't be started because ARM is shutting down");
2086 }
2087 return _("Unknown result code.");
2088}
2089
2090static void
2091service_manage_result_cb (void *cls, struct GNUNET_ARM_Handle *arm,
2092 enum GNUNET_ARM_RequestStatus rs,
2093 const char *service, enum GNUNET_ARM_Result result)
2094{
2095 struct ManageServiceContext *mctx = cls;
2096 char *emsg;
2097
2098 emsg = NULL;
2099 if (GNUNET_YES == mctx->expired)
2100 return;
2101 if (GNUNET_ARM_REQUEST_SENT_OK != rs)
2102 {
2103 GNUNET_asprintf (&emsg, "Error communicating with Peer %u's ARM: %s",
2104 mctx->peer->id, arm_req_string (rs));
2105 goto ret;
2106 }
2107 if (1 == mctx->start)
2108 goto service_start_check;
2109 if (! ((GNUNET_ARM_RESULT_STOPPED == result)
2110 || (GNUNET_ARM_RESULT_STOPPING == result)
2111 || (GNUNET_ARM_RESULT_IS_STOPPING_ALREADY == result)
2112 || (GNUNET_ARM_RESULT_IS_STOPPED_ALREADY == result)) )
2113 {
2114 /* stopping a service failed */
2115 GNUNET_asprintf (&emsg, arm_ret_string (result), service);
2116 goto ret;
2117 }
2118 /* service stopped successfully */
2119 goto ret;
2120
2121 service_start_check:
2122 if (! ((GNUNET_ARM_RESULT_STARTING == result)
2123 || (GNUNET_ARM_RESULT_IS_STARTING_ALREADY == result)
2124 || (GNUNET_ARM_RESULT_IS_STARTED_ALREADY == result)) )
2125 {
2126 /* starting a service failed */
2127 GNUNET_asprintf (&emsg, arm_ret_string (result), service);
2128 goto ret;
2129 }
2130 /* service started successfully */
2131
2132 ret:
2133 if (NULL != emsg)
2134 {
2135 LOG_DEBUG ("%s\n", emsg);
2136 GST_send_operation_fail_msg (mctx->client, mctx->op_id, emsg);
2137 }
2138 else
2139 send_operation_success_msg (mctx->client, mctx->op_id);
2140 GNUNET_free (emsg);
2141 cleanup_mctx (mctx);
2142}
2143
2144static void
2145handle_manage_peer_service (void *cls, struct GNUNET_SERVER_Client *client,
2146 const struct GNUNET_MessageHeader *message)
2147{
2148 const struct GNUNET_TESTBED_ManagePeerServiceMessage *msg;
2149 const char* service;
2150 struct Peer *peer;
2151 char *emsg;
2152 struct GNUNET_ARM_Handle *ah;
2153 struct ManageServiceContext *mctx;
2154 struct ForwardedOperationContext *fopc;
2155 uint64_t op_id;
2156 uint32_t peer_id;
2157 uint16_t msize;
2158
2159
2160 msize = ntohs (message->size);
2161 if (msize <= sizeof (struct GNUNET_TESTBED_ManagePeerServiceMessage))
2162 {
2163 GNUNET_break_op (0);
2164 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
2165 return;
2166 }
2167 msg = (const struct GNUNET_TESTBED_ManagePeerServiceMessage *) message;
2168 service = (const char *) &msg[1];
2169 if ('\0' != service[msize - sizeof
2170 (struct GNUNET_TESTBED_ManagePeerServiceMessage) - 1])
2171 {
2172 GNUNET_break_op (0);
2173 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
2174 return;
2175 }
2176 if (1 < msg->start)
2177 {
2178 GNUNET_break_op (0);
2179 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
2180 return;
2181 }
2182 peer_id = ntohl (msg->peer_id);
2183 op_id = GNUNET_ntohll (msg->operation_id);
2184 LOG_DEBUG ("Received request to manage service %s on peer %u\n",
2185 service, (unsigned int) peer_id);
2186 if ((GST_peer_list_size <= peer_id)
2187 || (NULL == (peer = GST_peer_list[peer_id])))
2188 {
2189 GNUNET_asprintf (&emsg, "Asked to manage service of a non existent peer "
2190 "with id: %u", peer_id);
2191 goto err_ret;
2192 }
2193 if (0 == strcasecmp ("arm", service))
2194 {
2195 emsg = GNUNET_strdup ("Cannot start/stop peer's ARM service. "
2196 "Use peer start/stop for that");
2197 goto err_ret;
2198 }
2199 if (GNUNET_YES == peer->is_remote)
2200 {
2201 /* Forward the destory message to sub controller */
2202 fopc = GNUNET_malloc (sizeof (struct ForwardedOperationContext));
2203 GNUNET_SERVER_client_keep (client);
2204 fopc->client = client;
2205 fopc->cls = peer;
2206 fopc->type = OP_MANAGE_SERVICE;
2207 fopc->operation_id = op_id;
2208 fopc->opc =
2209 GNUNET_TESTBED_forward_operation_msg_ (peer->details.remote.
2210 slave->controller,
2211 fopc->operation_id, &msg->header,
2212 &GST_forwarded_operation_reply_relay,
2213 fopc);
2214 fopc->timeout_task =
2215 GNUNET_SCHEDULER_add_delayed (GST_timeout, &GST_forwarded_operation_timeout,
2216 fopc);
2217 GNUNET_CONTAINER_DLL_insert_tail (fopcq_head, fopcq_tail, fopc);
2218 GNUNET_SERVER_receive_done (client, GNUNET_OK);
2219 return;
2220 }
2221 if ((0 != peer->reference_cnt)
2222 && ( (0 == strcasecmp ("core", service))
2223 || (0 == strcasecmp ("transport", service)) ) )
2224 {
2225 GNUNET_asprintf (&emsg, "Cannot stop %s service of peer with id: %u "
2226 "since it is required by existing operations",
2227 service, peer_id);
2228 goto err_ret;
2229 }
2230 ah = GNUNET_ARM_connect (peer->details.local.cfg, NULL, NULL);
2231 if (NULL == ah)
2232 {
2233 GNUNET_asprintf (&emsg,
2234 "Cannot connect to ARM service of peer with id: %u",
2235 peer_id);
2236 goto err_ret;
2237 }
2238 mctx = GNUNET_malloc (sizeof (struct ManageServiceContext));
2239 mctx->peer = peer;
2240 peer->reference_cnt++;
2241 mctx->op_id = op_id;
2242 mctx->ah = ah;
2243 GNUNET_SERVER_client_keep (client);
2244 mctx->client = client;
2245 mctx->start = msg->start;
2246 GNUNET_CONTAINER_DLL_insert_tail (mctx_head, mctx_tail, mctx);
2247 if (1 == mctx->start)
2248 GNUNET_ARM_request_service_start (mctx->ah, service,
2249 GNUNET_OS_INHERIT_STD_ERR,
2250 GST_timeout,
2251 service_manage_result_cb,
2252 mctx);
2253 else
2254 GNUNET_ARM_request_service_stop (mctx->ah, service,
2255 GST_timeout,
2256 service_manage_result_cb,
2257 mctx);
2258 GNUNET_SERVER_receive_done (client, GNUNET_OK);
2259 return;
2260
2261 err_ret:
2262 LOG (GNUNET_ERROR_TYPE_ERROR, "%s\n", emsg);
2263 GST_send_operation_fail_msg (client, op_id, emsg);
2264 GNUNET_free (emsg);
2265 GNUNET_SERVER_receive_done (client, GNUNET_OK);
2266}
1993 2267
1994/** 2268/**
1995 * Clears the forwarded operations queue 2269 * Clears the forwarded operations queue
@@ -2028,6 +2302,7 @@ clear_fopcq ()
2028 case OP_OVERLAY_CONNECT: 2302 case OP_OVERLAY_CONNECT:
2029 case OP_LINK_CONTROLLERS: 2303 case OP_LINK_CONTROLLERS:
2030 case OP_GET_SLAVE_CONFIG: 2304 case OP_GET_SLAVE_CONFIG:
2305 case OP_MANAGE_SERVICE:
2031 break; 2306 break;
2032 case OP_FORWARDED: 2307 case OP_FORWARDED:
2033 GNUNET_assert (0); 2308 GNUNET_assert (0);
@@ -2169,6 +2444,7 @@ handle_shutdown_peers (void *cls, struct GNUNET_SERVER_Client *client,
2169 msg = (const struct GNUNET_TESTBED_ShutdownPeersMessage *) message; 2444 msg = (const struct GNUNET_TESTBED_ShutdownPeersMessage *) message;
2170 LOG_DEBUG ("Received SHUTDOWN_PEERS\n"); 2445 LOG_DEBUG ("Received SHUTDOWN_PEERS\n");
2171 /* Stop and destroy all peers */ 2446 /* Stop and destroy all peers */
2447 free_mctxq ();
2172 GST_free_occq (); 2448 GST_free_occq ();
2173 GST_free_roccq (); 2449 GST_free_roccq ();
2174 clear_fopcq (); 2450 clear_fopcq ();
@@ -2310,6 +2586,7 @@ shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
2310 GNUNET_CONTAINER_DLL_remove (lcfq_head, lcfq_tail, lcfq); 2586 GNUNET_CONTAINER_DLL_remove (lcfq_head, lcfq_tail, lcfq);
2311 GNUNET_free (lcfq); 2587 GNUNET_free (lcfq);
2312 } 2588 }
2589 free_mctxq ();
2313 GST_free_occq (); 2590 GST_free_occq ();
2314 GST_free_roccq (); 2591 GST_free_roccq ();
2315 /* Clear peer list */ 2592 /* Clear peer list */
@@ -2435,6 +2712,8 @@ testbed_run (void *cls, struct GNUNET_SERVER_Handle *server,
2435 sizeof (struct GNUNET_TESTBED_OverlayConnectMessage)}, 2712 sizeof (struct GNUNET_TESTBED_OverlayConnectMessage)},
2436 {&GST_handle_remote_overlay_connect, NULL, 2713 {&GST_handle_remote_overlay_connect, NULL,
2437 GNUNET_MESSAGE_TYPE_TESTBED_REMOTE_OVERLAY_CONNECT, 0}, 2714 GNUNET_MESSAGE_TYPE_TESTBED_REMOTE_OVERLAY_CONNECT, 0},
2715 {&handle_manage_peer_service, NULL,
2716 GNUNET_MESSAGE_TYPE_TESTBED_MANAGE_PEER_SERVICE, 0},
2438 {&handle_slave_get_config, NULL, 2717 {&handle_slave_get_config, NULL,
2439 GNUNET_MESSAGE_TYPE_TESTBED_GET_SLAVE_CONFIGURATION, 2718 GNUNET_MESSAGE_TYPE_TESTBED_GET_SLAVE_CONFIGURATION,
2440 sizeof (struct GNUNET_TESTBED_SlaveGetConfigurationMessage)}, 2719 sizeof (struct GNUNET_TESTBED_SlaveGetConfigurationMessage)},