[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] r29989 - msh/src
From: |
gnunet |
Subject: |
[GNUnet-SVN] r29989 - msh/src |
Date: |
Tue, 8 Oct 2013 15:41:31 +0200 |
Author: harsha
Date: 2013-10-08 15:41:31 +0200 (Tue, 08 Oct 2013)
New Revision: 29989
Modified:
msh/src/mshd-server.c
Log:
- use server notification context
Modified: msh/src/mshd-server.c
===================================================================
--- msh/src/mshd-server.c 2013-10-08 13:02:46 UTC (rev 29988)
+++ msh/src/mshd-server.c 2013-10-08 13:41:31 UTC (rev 29989)
@@ -10,8 +10,10 @@
#include <gnunet/gnunet_util_lib.h>
#include "mshd.h"
#include "addressmap.h"
+#include "mshd_pmonitor.h"
+#include "util.h"
-#define MESSAGE_SEND_TIMEOUT(s) \
+#define TIMEOUT_SECS(s) \
GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, s)
#define LOG(kind,...) \
@@ -35,42 +37,24 @@
static struct GNUNET_SERVER_Handle *daemon_serv;
/**
- * Our UID. We use this for access checks
+ * Notification queue for the local server
*/
-uid_t our_uid;
+static struct GNUNET_SERVER_NotificationContext *local_serv_nc;
/**
- * Our GID. We use this for access checks
+ * Notification queue for the daemon server
*/
-uid_t our_gid;
+static struct GNUNET_SERVER_NotificationContext *daemon_serv_nc;
-
/**
- * Message queue for transmitting messages
+ * Our UID. We use this for access checks
*/
-struct MessageQueue
-{
- /**
- * next pointer for DLL
- */
- struct MessageQueue *next;
+uid_t our_uid;
- /**
- * prev pointer for DLL
- */
- struct MessageQueue *prev;
-
- /**
- * The message to be sent
- */
- struct GNUNET_MessageHeader *msg;
-};
-
-
/**
- * Context associated with each client instance
+ * Our GID. We use this for access checks
*/
-struct ClientCtx;
+uid_t our_gid;
/**
@@ -79,9 +63,9 @@
struct ExecCtx
{
/**
- * associated client context
+ * The client handle this context is associated with
*/
- struct ClientCtx *client_ctx;
+ struct GNUNET_SERVER_Client *client;
/**
* The command strings to execute
@@ -142,45 +126,6 @@
/**
- * Context associated with each client instance
- */
-struct ClientCtx
-{
- /**
- * The client handle
- */
- struct GNUNET_SERVER_Client *client;
-
- /**
- * the transmission handle
- */
- struct GNUNET_SERVER_TransmitHandle *tx;
-
- /**
- * message queue head
- */
- struct MessageQueue *mq_head;
-
- /**
- * message queue tail
- */
- struct MessageQueue *mq_tail;
-
- /**
- * execution context. Set this for remote clients which ask us to execute a
- * command
- */
- struct ExecCtx *exec_ctx;
-
- /**
- * Is the client currently suspended? i.e do we have to call receive_done
- * after transmitting a message to the client?
- */
- int suspended;
-};
-
-
-/**
* Destroys an execution context
*
* @param ctx execution context
@@ -190,6 +135,7 @@
{
unsigned int cnt;
+ GNUNET_SERVER_client_drop (ctx->client);
if (NULL != ctx->args)
{
for (cnt = 0; NULL != ctx->args[cnt]; cnt++)
@@ -214,108 +160,6 @@
/**
- * Destroys a client context
- *
- * @param ctx the client context
- */
-static void
-destroy_client_ctx (struct ClientCtx *ctx)
-{
- struct MessageQueue *mq;
-
- if (NULL != ctx->tx)
- GNUNET_SERVER_notify_transmit_ready_cancel (ctx->tx);
- GNUNET_assert (NULL == ctx->client);
- while (NULL != (mq = ctx->mq_head))
- {
- GNUNET_free (mq->msg);
- GNUNET_CONTAINER_DLL_remove (ctx->mq_head, ctx->mq_tail, mq);
- GNUNET_free (mq);
- }
- if (NULL != ctx->exec_ctx)
- destroy_exec_ctx (ctx->exec_ctx);
- GNUNET_free (ctx);
-}
-
-
-/**
- * Function called to notify a client about the connection
- * begin ready to queue more data. "buf" will be
- * NULL and "size" zero if the connection was closed for
- * writing in the meantime.
- *
- * @param cls client context
- * @param size number of bytes available in buf
- * @param buf where the callee should write the message
- * @return number of bytes written to buf
- */
-static size_t
-transmit_ready_cb (void *cls, size_t size, void *buf)
-{
- struct ClientCtx *ctx = cls;
- struct GNUNET_SERVER_Client *client = ctx->client;
- struct MessageQueue *mq;
- struct GNUNET_MessageHeader *msg;
- size_t wrote;
-
- ctx->tx = NULL;
- wrote = 0;
- if ((0 == size) || (NULL == buf))
- {
- GNUNET_assert (NULL != ctx->client);
- GNUNET_SERVER_client_drop (ctx->client);
- ctx->client = NULL;
- return 0;
- }
- mq = ctx->mq_head;
- msg = mq->msg;
- wrote = ntohs (msg->size);
- GNUNET_assert (size >= wrote);
- (void) memcpy (buf, msg, wrote);
- GNUNET_CONTAINER_DLL_remove (ctx->mq_head, ctx->mq_tail, mq);
- GNUNET_free (mq->msg);
- GNUNET_free (mq);
- if (NULL != (mq = ctx->mq_head))
- ctx->tx = GNUNET_SERVER_notify_transmit_ready (client, ntohs (msg->size),
- MESSAGE_SEND_TIMEOUT (30),
- &transmit_ready_cb, ctx);
- if (GNUNET_YES == ctx->suspended)
- {
- GNUNET_SERVER_receive_done (client, GNUNET_YES);
- ctx->suspended = GNUNET_NO;
- }
- return wrote;
-}
-
-
-/**
- * Queue a message into a clients message queue
- *
- * @param ctx the context associated with the client
- * @param msg the message to queue. Will be consumed
- * @param suspended is the client suspended at the time of calling
queue_message
- */
-static void
-queue_message (struct ClientCtx *ctx, struct GNUNET_MessageHeader *msg,
- int suspended)
-{
- struct MessageQueue *mq;
- struct GNUNET_SERVER_Client *client = ctx->client;
-
- GNUNET_assert (!(ctx->suspended && suspended));
- if (GNUNET_YES == suspended)
- ctx->suspended = GNUNET_YES;
- mq = GNUNET_malloc (sizeof (struct MessageQueue));
- mq->msg = msg;
- GNUNET_CONTAINER_DLL_insert_tail (ctx->mq_head, ctx->mq_tail, mq);
- if (NULL == ctx->tx)
- ctx->tx = GNUNET_SERVER_notify_transmit_ready (client, ntohs (msg->size),
- MESSAGE_SEND_TIMEOUT (30),
- &transmit_ready_cb, ctx);
-}
-
-
-/**
* Parse contingious 0-terminated strings from a buffer of given length
*
* @param buf the buffer
@@ -390,7 +234,6 @@
handle_addresslookup (void *cls, struct GNUNET_SERVER_Client *client,
const struct GNUNET_MessageHeader* message)
{
- struct ClientCtx *ctx;
const struct MSH_MSG_AddressLookup *msg;
struct MSH_MSG_AddressLookupReply *reply;
struct InstanceAddr *iaddr;
@@ -401,8 +244,6 @@
emsg = NULL;
port = 0;
- ctx = GNUNET_SERVER_client_get_user_context (client, struct ClientCtx);
- GNUNET_assert (NULL != ctx);
msg = (const struct MSH_MSG_AddressLookup *) message;
ip = ntohl (msg->ip);
if (GNUNET_NO == reversemap_check (rmap, ip))
@@ -424,8 +265,10 @@
reply->header.type = htons (MSH_MTYPE_ADDRESS_LOOKUP_REPLY);
reply->port = htons (port);
if (NULL != emsg)
- (void) strcpy (reply->emsg, emsg);
- queue_message (ctx, &reply->header, GNUNET_YES);
+ (void) strcpy (reply->emsg, emsg);
+ GNUNET_SERVER_notification_context_unicast (local_serv_nc, client,
+ &reply->header, GNUNET_NO);
+ GNUNET_SERVER_receive_done (client, GNUNET_OK);
}
@@ -457,14 +300,11 @@
handle_auth_challenge (void *cls, struct GNUNET_SERVER_Client *client,
const struct GNUNET_MessageHeader* message)
{
- struct ClientCtx *ctx;
const struct MSH_MSG_Challenge *msg;
struct MSH_MSG_ChallengeResponse *reply;
struct GNUNET_HashCode salt;
struct GNUNET_HashCode cred;
- ctx = GNUNET_SERVER_client_get_user_context (client, struct ClientCtx);
- GNUNET_assert (NULL != ctx);
msg = (const struct MSH_MSG_Challenge *) message;
LOG_DEBUG ("Challenge nonce: %104s\n", msg->salt.encoding);
GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_hash_from_string
@@ -474,7 +314,9 @@
reply->header.size = htons (sizeof (struct MSH_MSG_ChallengeResponse));
reply->header.type = htons (MSH_MTYPE_CHALLENGE_RESPONSE);
GNUNET_CRYPTO_hash_to_enc (&cred, &reply->auth);
- queue_message (ctx, &reply->header, GNUNET_YES);
+ GNUNET_SERVER_notification_context_unicast (local_serv_nc, client,
+ &reply->header, GNUNET_NO);
+ GNUNET_SERVER_receive_done (client, GNUNET_OK);
}
@@ -508,43 +350,13 @@
static void
local_server_connect (void *cls, struct GNUNET_SERVER_Client *client)
{
- struct ClientCtx *ctx;
-
if (NULL == client) /* Server shutting down */
return;
- GNUNET_SERVER_client_keep (client);
- ctx = GNUNET_malloc (sizeof (struct ClientCtx ));
- ctx->client = client;
- GNUNET_SERVER_client_set_user_context (client, ctx);
+ GNUNET_SERVER_notification_context_add (local_serv_nc, client);
}
/**
- * Callback to be called when ever a client connects to the local server
- *
- * @param cls NULL
- * @param client the client handle
- */
-static void
-local_server_disconnect (void *cls, struct GNUNET_SERVER_Client *client)
-{
- struct ClientCtx *ctx;
-
- if (NULL == client)
- return;
- LOG_DEBUG ("A local client has disconnected\n");
- ctx = GNUNET_SERVER_client_get_user_context (client, struct ClientCtx);
- GNUNET_assert (NULL != ctx);
- if (NULL != ctx->client)
- {
- GNUNET_SERVER_client_drop (ctx->client);
- ctx->client = NULL;
- }
- destroy_client_ctx (ctx);
-}
-
-
-/**
* Initialise the local server
*
* @param unixpath the name to use while opening the abstract UNIX domain
socket
@@ -588,7 +400,7 @@
}
GNUNET_SERVER_add_handlers (local_serv, handlers);
GNUNET_SERVER_connect_notify (local_serv, &local_server_connect, NULL);
- GNUNET_SERVER_disconnect_notify (local_serv, &local_server_disconnect, NULL);
+ local_serv_nc = GNUNET_SERVER_notification_context_create (local_serv, 1);
return GNUNET_OK;
}
@@ -626,15 +438,13 @@
struct GNUNET_SERVER_Client *client,
const struct GNUNET_MessageHeader* message)
{
- struct ClientCtx *ctx;
struct ExecCtx *exec_ctx;
const struct MSH_MSG_RunCmd *msg;
struct GNUNET_MessageHeader *reply;
uint16_t size;
LOG_DEBUG ("Received a RUN_CMD message\n");
- ctx = GNUNET_SERVER_client_get_user_context (client, struct ClientCtx);
- exec_ctx = ctx->exec_ctx;
+ exec_ctx = GNUNET_SERVER_client_get_user_context (client, struct ExecCtx);
GNUNET_assert (NULL != exec_ctx);
if (NULL != exec_ctx->args)
{
@@ -657,37 +467,18 @@
}
reply = create_challenge_message (exec_ctx);
LOG_DEBUG ("Sending AUTH_CHALLENGE\n");
- queue_message (ctx, reply, GNUNET_YES);
+ GNUNET_SERVER_notification_context_unicast (daemon_serv_nc, client, reply,
+ GNUNET_NO);
+ GNUNET_SERVER_receive_done (client, GNUNET_OK);
return;
close_conn:
GNUNET_break_op (0);
GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
- GNUNET_SERVER_client_drop (ctx->client);
- ctx->client = NULL;
}
/**
- * Function to call for access control checks.
- *
- * @param cls closure
- * @param ucred credentials, if available, otherwise NULL
- * @param addr address
- * @param addrlen length of address
- * @return GNUNET_YES to allow, GNUNET_NO to deny, GNUNET_SYSERR
- * for unknown address family (will be denied).
- */
-static int
-check_remote_access (void *cls,
- const struct GNUNET_CONNECTION_Credentials *cred,
- const struct sockaddr * addr, socklen_t addrlen)
-{
- return GNUNET_YES;
-}
-
-
-/**
* Task to read the output from a process and send it to client
*
* @param cls the client context
@@ -696,8 +487,7 @@
static void
read_fout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
- struct ClientCtx *ctx = cls;
- struct ExecCtx *exec_ctx = ctx->exec_ctx;
+ struct ExecCtx *exec_ctx = cls;
struct MSH_MSG_CmdIO *msg;
static char data[MAX_IO_DATA];
ssize_t size;
@@ -712,7 +502,7 @@
if (size <= 0)
{
GNUNET_break (GNUNET_SYSERR != size);
- GNUNET_SERVER_client_disconnect (ctx->client);
+ GNUNET_SERVER_client_disconnect (exec_ctx->client);
return;
}
msize = size + sizeof (struct MSH_MSG_CmdIO);
@@ -720,10 +510,11 @@
msg->header.type = htons (MSH_MTYPE_CMD_STREAM_STDOUT);
msg->header.size = htons (msize);
memcpy (msg->data, data, size);
- queue_message (ctx, &msg->header, GNUNET_NO);
+ GNUNET_SERVER_notification_context_unicast (daemon_serv_nc, exec_ctx->client,
+ &msg->header, GNUNET_NO);
exec_ctx->fout_task =
GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
- exec_ctx->fout, &read_fout, ctx);
+ exec_ctx->fout, &read_fout, exec_ctx);
}
@@ -739,14 +530,13 @@
static void
proc_exit_cb (void *cls, enum GNUNET_OS_ProcessStatusType type, int code)
{
- struct ClientCtx *ctx = cls;
- struct ExecCtx *exec_ctx = ctx->exec_ctx;
+ struct ExecCtx *exec_ctx = cls;
LOG_DEBUG ("Command `%s' exited.\n", exec_ctx->args[0]);
GNUNET_OS_process_destroy (exec_ctx->proc);
exec_ctx->proc = NULL;
GNUNET_SCHEDULER_cancel (exec_ctx->fout_task);
- exec_ctx->fout_task = GNUNET_SCHEDULER_add_now (&read_fout, ctx);
+ exec_ctx->fout_task = GNUNET_SCHEDULER_add_now (&read_fout, exec_ctx);
}
@@ -773,7 +563,7 @@
ctx->args);
if (NULL == ctx->proc)
return GNUNET_SYSERR;
- MSH_monitor_process (ctx->proc, &proc_exit_cb, ctx->client_ctx);
+ MSH_monitor_process (ctx->proc, &proc_exit_cb, ctx);
ctx->fin = GNUNET_DISK_pipe_detach_end (pin, GNUNET_DISK_PIPE_END_WRITE);
ctx->fout = GNUNET_DISK_pipe_detach_end (pout, GNUNET_DISK_PIPE_END_READ);
GNUNET_assert ((NULL != ctx->fin && (NULL != ctx->fout)));
@@ -781,7 +571,7 @@
GNUNET_assert (GNUNET_OK == GNUNET_DISK_pipe_close (pout));
ctx->fout_task =
GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
- ctx->fout, &read_fout, ctx->client_ctx);
+ ctx->fout, &read_fout, ctx);
return GNUNET_OK;
}
@@ -801,18 +591,11 @@
{
const struct MSH_MSG_ChallengeResponse *msg;
struct GNUNET_MessageHeader *reply;
- struct ClientCtx *ctx;
struct ExecCtx *exec_ctx;
struct GNUNET_HashCode cred;
struct GNUNET_CRYPTO_HashAsciiEncoded enc;
- ctx = GNUNET_SERVER_client_get_user_context (client, struct ClientCtx);
- if (NULL == ctx)
- {
- GNUNET_break_op (0);
- goto err_ret;
- }
- exec_ctx = ctx->exec_ctx;
+ exec_ctx = GNUNET_SERVER_client_get_user_context (client, struct ExecCtx);
GNUNET_assert (NULL != exec_ctx);
auth_challenge_cred (&exec_ctx->salt, &cred);
GNUNET_CRYPTO_hash_to_enc (&cred, &enc);
@@ -836,13 +619,13 @@
reply = GNUNET_malloc (sizeof (struct GNUNET_MessageHeader));
reply->size = htons (sizeof (struct GNUNET_MessageHeader));
reply->type = htons (MSH_MTYPE_EXEC_BEGIN);
- queue_message (ctx, reply, GNUNET_YES);
+ GNUNET_SERVER_notification_context_unicast (daemon_serv_nc, exec_ctx->client,
+ reply, GNUNET_NO);
+ GNUNET_SERVER_receive_done (client, GNUNET_OK);
return;
err_ret:
GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
- GNUNET_SERVER_client_drop (ctx->client);
- ctx->client = NULL;
}
@@ -855,8 +638,7 @@
static void
write_fin (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
- struct ClientCtx *ctx = cls;
- struct ExecCtx *exec_ctx = ctx->exec_ctx;
+ struct ExecCtx *exec_ctx = cls;
ssize_t wrote;
exec_ctx->fin_task = GNUNET_SCHEDULER_NO_TASK;
@@ -879,7 +661,7 @@
GNUNET_free (exec_ctx->buf);
exec_ctx->buf = NULL;
exec_ctx->bufsize = 0;
- GNUNET_SERVER_receive_done (ctx->client, GNUNET_OK);
+ GNUNET_SERVER_receive_done (exec_ctx->client, GNUNET_OK);
return;
}
GNUNET_assert (wrote < exec_ctx->bufsize);
@@ -890,13 +672,11 @@
exec_ctx->fin_task =
GNUNET_SCHEDULER_add_write_file (GNUNET_TIME_UNIT_FOREVER_REL,
exec_ctx->fin,
- &write_fin, ctx);
+ &write_fin, exec_ctx);
return;
err_ret:
- GNUNET_SERVER_receive_done (ctx->client, GNUNET_SYSERR);
- GNUNET_SERVER_client_drop (ctx->client);
- ctx->client = NULL;
+ GNUNET_SERVER_receive_done (exec_ctx->client, GNUNET_SYSERR);
}
@@ -914,7 +694,6 @@
const struct GNUNET_MessageHeader* message)
{
const struct MSH_MSG_CmdIO *msg;
- struct ClientCtx *ctx;
struct ExecCtx *exec_ctx;
ssize_t wrote;
uint16_t size;
@@ -922,9 +701,7 @@
LOG_DEBUG ("Received CMD_IO_STDIN message\n");
size = ntohs (message->size);
msg = (const struct MSH_MSG_CmdIO *) message;
- ctx = GNUNET_SERVER_client_get_user_context (client, struct ClientCtx);
- GNUNET_assert (NULL != ctx);
- exec_ctx = ctx->exec_ctx;
+ exec_ctx = GNUNET_SERVER_client_get_user_context (client, struct ExecCtx);
GNUNET_assert (NULL != exec_ctx);
size -= sizeof (struct MSH_MSG_CmdIO);
wrote = GNUNET_DISK_file_write (exec_ctx->fin, msg->data, size);
@@ -932,8 +709,6 @@
{
LOG_ERROR ("Error writing to proc's STDIN\n");
GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
- GNUNET_SERVER_client_drop (ctx->client);
- ctx->client = NULL;
return;
}
LOG_DEBUG ("Wrote %zd to proc's STDIN\n", wrote);
@@ -952,13 +727,13 @@
exec_ctx->fin_task =
GNUNET_SCHEDULER_add_write_file (GNUNET_TIME_UNIT_FOREVER_REL,
exec_ctx->fin,
- &write_fin, ctx);
+ &write_fin, exec_ctx);
GNUNET_SERVER_disable_receive_done_warning (client);
}
/**
- * Callback to be called when ever a client connects to the local server
+ * Callback to be called when ever a client connects to the daemon server
*
* @param cls NULL
* @param client the client handle
@@ -966,19 +741,14 @@
static void
daemon_server_disconnect (void *cls, struct GNUNET_SERVER_Client *client)
{
- struct ClientCtx *ctx;
+ struct ExecCtx *exec_ctx;
if (NULL == client)
return;
LOG_DEBUG ("A remote client has disconnected\n");
- ctx = GNUNET_SERVER_client_get_user_context (client, struct ClientCtx);
- GNUNET_assert (NULL != ctx);
- if (NULL != ctx->client)
- {
- GNUNET_SERVER_client_drop (ctx->client);
- ctx->client = NULL;
- }
- destroy_client_ctx (ctx);
+ exec_ctx = GNUNET_SERVER_client_get_user_context (client, struct ExecCtx);
+ GNUNET_assert (NULL != exec_ctx);
+ destroy_exec_ctx (exec_ctx);
}
@@ -1007,6 +777,7 @@
return GNUNET_SYSERR;
GNUNET_SERVER_add_handlers (daemon_serv, handlers);
GNUNET_SERVER_disconnect_notify (daemon_serv, &daemon_server_disconnect,
NULL);
+ daemon_serv_nc = GNUNET_SERVER_notification_context_create (daemon_serv, 1);
return GNUNET_OK;
}
@@ -1021,11 +792,10 @@
static void
timeout_cb (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
- struct ClientCtx *ctx = cls;
- struct ExecCtx *exec_ctx = ctx->exec_ctx;
+ struct ExecCtx *exec_ctx = cls;
exec_ctx->timeout_task = GNUNET_SCHEDULER_NO_TASK;
- destroy_client_ctx (ctx);
+ GNUNET_SERVER_client_disconnect (exec_ctx->client);
}
@@ -1038,21 +808,17 @@
daemon_server_add_connection (struct GNUNET_CONNECTION_Handle *conn,
int conn_fd)
{
- struct ClientCtx *ctx;
struct ExecCtx *exec_ctx;
+ struct GNUNET_SERVER_Client *client;
- ctx = GNUNET_malloc (sizeof (struct ClientCtx));
exec_ctx = GNUNET_malloc (sizeof (struct ExecCtx));
-
- exec_ctx->client_ctx = ctx;
- ctx->exec_ctx = exec_ctx;
exec_ctx->conn_fd = conn_fd;
- ctx->client = GNUNET_SERVER_connect_socket (daemon_serv, conn);
- GNUNET_SERVER_client_set_user_context (ctx->client, ctx);
+ client = GNUNET_SERVER_connect_socket (daemon_serv, conn);
+ exec_ctx->client = client;
+ GNUNET_SERVER_client_set_user_context (client, exec_ctx);
+ GNUNET_SERVER_notification_context_add (daemon_serv_nc, client);
exec_ctx->timeout_task =
- GNUNET_SCHEDULER_add_delayed
- (GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30),
- &timeout_cb, ctx);
+ GNUNET_SCHEDULER_add_delayed (TIMEOUT_SECS (30), &timeout_cb, exec_ctx);
}
@@ -1067,6 +833,11 @@
GNUNET_SERVER_destroy (daemon_serv);
daemon_serv = NULL;
}
+ if (NULL != daemon_serv_nc)
+ {
+ GNUNET_SERVER_notification_context_destroy (daemon_serv_nc);
+ daemon_serv_nc = NULL;
+ }
}
/* End of mshd-server.c */
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r29989 - msh/src,
gnunet <=