summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac9
-rw-r--r--pkgconfig/gnunetsocial.pc12
-rw-r--r--src/Makefile.am1
-rw-r--r--src/include/gnunet_env_lib.h3
-rw-r--r--src/include/gnunet_protocols.h40
-rw-r--r--src/include/gnunet_social_service.h27
-rw-r--r--src/multicast/multicast.conf.in11
-rw-r--r--src/psyc/gnunet-service-psyc.c4
-rw-r--r--src/psyc/psyc.conf.in8
-rw-r--r--src/psyc/test_psyc.conf2
-rw-r--r--src/psycstore/psycstore.conf.in11
-rw-r--r--src/social/Makefile.am78
-rw-r--r--src/social/gnunet-service-social.c461
-rw-r--r--src/social/social.conf.in12
-rw-r--r--src/social/social.h46
-rw-r--r--src/social/social_api.c627
-rw-r--r--src/social/test_social.c158
-rw-r--r--src/social/test_social.conf2
18 files changed, 1479 insertions, 33 deletions
diff --git a/configure.ac b/configure.ac
index 684b4f788..5a0f19d2b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1411,6 +1411,8 @@ src/ats/ats.conf
src/ats-tool/Makefile
src/ats-tests/Makefile
src/block/Makefile
+src/cadet/Makefile
+src/cadet/cadet.conf
src/core/Makefile
src/core/core.conf
src/consensus/Makefile
@@ -1443,8 +1445,6 @@ src/identity/identity.conf
src/include/Makefile
src/integration-tests/Makefile
src/hostlist/Makefile
-src/cadet/Makefile
-src/cadet/cadet.conf
src/multicast/Makefile
src/multicast/multicast.conf
src/mysql/Makefile
@@ -1478,6 +1478,8 @@ src/scalarproduct/Makefile
src/scalarproduct/scalarproduct.conf
src/set/Makefile
src/set/set.conf
+src/social/Makefile
+src/social/social.conf
src/statistics/Makefile
src/statistics/statistics.conf
src/template/Makefile
@@ -1496,6 +1498,7 @@ pkgconfig/Makefile
pkgconfig/gnunetarm.pc
pkgconfig/gnunetats.pc
pkgconfig/gnunetblock.pc
+pkgconfig/gnunetcadet.pc
pkgconfig/gnunetconsensus.pc
pkgconfig/gnunetconversation.pc
pkgconfig/gnunetcore.pc
@@ -1512,7 +1515,6 @@ pkgconfig/gnunetfs.pc
pkgconfig/gnunetgns.pc
pkgconfig/gnunethello.pc
pkgconfig/gnunetidentity.pc
-pkgconfig/gnunetcadet.pc
pkgconfig/gnunetmicrophone.pc
pkgconfig/gnunetmulticast.pc
pkgconfig/gnunetmysql.pc
@@ -1527,6 +1529,7 @@ pkgconfig/gnunetregex.pc
pkgconfig/gnunetrevocation.pc
pkgconfig/gnunetscalarproduct.pc
pkgconfig/gnunetset.pc
+pkgconfig/gnunetsocial.pc
pkgconfig/gnunetspeaker.pc
pkgconfig/gnunetstatistics.pc
pkgconfig/gnunettestbed.pc
diff --git a/pkgconfig/gnunetsocial.pc b/pkgconfig/gnunetsocial.pc
new file mode 100644
index 000000000..9f991409d
--- /dev/null
+++ b/pkgconfig/gnunetsocial.pc
@@ -0,0 +1,12 @@
+prefix=/usr/local
+exec_prefix=${prefix}
+libdir=${exec_prefix}/lib
+includedir=${prefix}/include
+
+Name: GNUnet Social
+Description: library for social interactions
+URL: https://gnunet.org
+Version: 0.10.1
+Requires:
+Libs: -L${libdir} -lgnunetsocial
+Cflags: -I${includedir}
diff --git a/src/Makefile.am b/src/Makefile.am
index 8aef2f38f..e339abf6d 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -20,6 +20,7 @@ if HAVE_EXPERIMENTAL
env \
psycstore \
psyc \
+ social \
$(CONSENSUS) \
$(SECRETSHARING) \
$(SCALARPRODUCT) \
diff --git a/src/include/gnunet_env_lib.h b/src/include/gnunet_env_lib.h
index 8ff37b7a7..5d1d013a3 100644
--- a/src/include/gnunet_env_lib.h
+++ b/src/include/gnunet_env_lib.h
@@ -93,7 +93,8 @@ enum GNUNET_ENV_Type
/**
* PSYC state modifier.
*/
-struct GNUNET_ENV_Modifier {
+struct GNUNET_ENV_Modifier
+{
/**
* State operation.
*/
diff --git a/src/include/gnunet_protocols.h b/src/include/gnunet_protocols.h
index fba99ff43..855ee0703 100644
--- a/src/include/gnunet_protocols.h
+++ b/src/include/gnunet_protocols.h
@@ -2171,13 +2171,13 @@ extern "C"
/** S->C: result of an operation */
#define GNUNET_MESSAGE_TYPE_PSYC_RESULT_CODE 680
-/** C->S: request to start a master */
+/** C->S: request to start a channel as a master */
#define GNUNET_MESSAGE_TYPE_PSYC_MASTER_START 681
/** S->C: master start acknowledgement */
#define GNUNET_MESSAGE_TYPE_PSYC_MASTER_START_ACK 682
-/** C->S: request to start a master */
+/** C->S: request to join a channel as a slave */
#define GNUNET_MESSAGE_TYPE_PSYC_SLAVE_JOIN 683
/** S->C: slave join acknowledgement */
@@ -2489,14 +2489,42 @@ extern "C"
#define GNUNET_MESSAGE_TYPE_PEERSTORE_ITERATE_END 825
-/**
- * Next available: 840
- */
-
/*******************************************************************************
* SOCIAL message types
******************************************************************************/
+/**
+ * C: client
+ * S: service
+ * P: PSYC
+ */
+
+/** S->C: result of an operation */
+#define GNUNET_MESSAGE_TYPE_SOCIAL_RESULT_CODE 840
+
+/** C->S: request to enter a home as the host */
+#define GNUNET_MESSAGE_TYPE_SOCIAL_HOME_ENTER 841
+
+/** S->C: home enter acknowledgement */
+#define GNUNET_MESSAGE_TYPE_SOCIAL_HOME_ENTER_ACK 842
+
+/** C->S: request to enter a place as a guest */
+#define GNUNET_MESSAGE_TYPE_SOCIAL_PLACE_ENTER 843
+
+/** S->C: guest join acknowledgement */
+#define GNUNET_MESSAGE_TYPE_SOCIAL_PLACE_ENTER_ACK 844
+
+/** P->S->C: incoming join request from PSYC */
+#define GNUNET_MESSAGE_TYPE_SOCIAL_JOIN_REQUEST 847
+
+/** C->S->P: decision about a join request */
+#define GNUNET_MESSAGE_TYPE_SOCIAL_JOIN_DECISION 848
+
+
+/**
+ * Next available: 880
+ */
+
/**
* Type used to match 'all' message types.
diff --git a/src/include/gnunet_social_service.h b/src/include/gnunet_social_service.h
index 98ad88346..ba698aee6 100644
--- a/src/include/gnunet_social_service.h
+++ b/src/include/gnunet_social_service.h
@@ -36,9 +36,9 @@ extern "C"
#endif
#include "gnunet_util_lib.h"
-#include "gnunet_psyc_lib.h"
+#include "gnunet_env_lib.h"
+#include "gnunet_identity_service.h"
#include "gnunet_psyc_service.h"
-#include "gnunet_multicast_service.h"
/**
@@ -94,7 +94,7 @@ typedef int
const char *full_method_name,
uint64_t message_id,
size_t modifier_count,
- GNUNET_PSYC_Modifier *modifiers,
+ struct GNUNET_ENV_Modifier *modifiers,
uint64_t data_offset,
const void *data,
size_t data_size,
@@ -173,7 +173,7 @@ typedef void
struct GNUNET_SOCIAL_Nym *nym,
size_t variable_count,
const char *method_name,
- GNUNET_PSYC_Modifier *variables,
+ struct GNUNET_ENV_Modifier *variables,
const void *data,
size_t data_size);
@@ -193,7 +193,7 @@ typedef void
(*GNUNET_SOCIAL_FarewellCallback) (void *cls,
struct GNUNET_SOCIAL_Nym *nym,
size_t variable_count,
- GNUNET_PSYC_Modifier *variables);
+ struct GNUNET_ENV_Modifier *variables);
/**
@@ -313,22 +313,24 @@ GNUNET_SOCIAL_home_advertise (struct GNUNET_SOCIAL_Home *home,
const char *name,
size_t peer_count,
const struct GNUNET_PeerIdentity *peers,
- GNUNET_TIME_Relative expiration_time,
+ struct GNUNET_TIME_Relative expiration_time,
const char *password);
/**
* Flags for announcements in a home.
*/
-enum GNUNET_PSYC_AnnouncementFlags
+enum GNUNET_SOCIAL_AnnounceFlags
{
+ GNUNET_SOCIAL_ANNOUNCE_NONE = 0,
+
/**
* Whether this announcement removes all objects from the home.
*
* New objects can be still added to the now empty home using the @e env
* parameter of the same announcement.
*/
- GNUNET_SOCIAL_ANNOUNCEMENT_CLEAR_OBJECTS = 1 << 0
+ GNUNET_SOCIAL_ANNOUNCE_CLEAR_OBJECTS = 1 << 0
};
@@ -359,7 +361,7 @@ GNUNET_SOCIAL_home_announce (struct GNUNET_SOCIAL_Home *home,
const struct GNUNET_ENV_Environment *env,
GNUNET_CONNECTION_TransmitReadyNotify notify,
void *notify_cls,
- GNUNET_SOCIAL_AnnouncementFlags flags);
+ enum GNUNET_SOCIAL_AnnounceFlags flags);
/**
@@ -529,7 +531,10 @@ GNUNET_SOCIAL_place_look_at (struct GNUNET_SOCIAL_Place *place,
/**
* Flags for talking to the host of a place.
*/
-enum GNUNET_SOCIAL_TalkFlags;
+enum GNUNET_SOCIAL_TalkFlags
+{
+ GNUNET_SOCIAL_TALK_NONE = 0
+};
/**
@@ -555,7 +560,7 @@ GNUNET_SOCIAL_place_talk (struct GNUNET_SOCIAL_Place *place,
const struct GNUNET_ENV_Environment *env,
GNUNET_CONNECTION_TransmitReadyNotify notify,
void *notify_cls,
- GNUNET_SOCIAL_TalkFlags flags);
+ enum GNUNET_SOCIAL_TalkFlags flags);
/**
diff --git a/src/multicast/multicast.conf.in b/src/multicast/multicast.conf.in
index dab90c7eb..f4a6daa1e 100644
--- a/src/multicast/multicast.conf.in
+++ b/src/multicast/multicast.conf.in
@@ -1,13 +1,16 @@
[multicast]
AUTOSTART = @AUTOSTART@
-PORT = 2109
-HOSTNAME = localhost
BINARY = gnunet-service-multicast
-ACCEPT_FROM = 127.0.0.1;
-ACCEPT_FROM6 = ::1;
+
UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-multicast.sock
UNIX_MATCH_UID = YES
UNIX_MATCH_GID = YES
+
+@UNIXONLY@PORT = 2109
+HOSTNAME = localhost
+ACCEPT_FROM = 127.0.0.1;
+ACCEPT_FROM6 = ::1;
+
# DISABLE_SOCKET_FORWARDING = NO
# USERNAME =
# MAXBUF =
diff --git a/src/psyc/gnunet-service-psyc.c b/src/psyc/gnunet-service-psyc.c
index cef89b828..13f908b6c 100644
--- a/src/psyc/gnunet-service-psyc.c
+++ b/src/psyc/gnunet-service-psyc.c
@@ -327,7 +327,7 @@ struct Master
/**
* @see enum GNUNET_PSYC_Policy
*/
- uint32_t policy;
+ enum GNUNET_PSYC_Policy policy;
};
@@ -2062,4 +2062,4 @@ main (int argc, char *const *argv)
&run, NULL)) ? 0 : 1;
}
-/* end of gnunet-service-psycstore.c */
+/* end of gnunet-service-psyc.c */
diff --git a/src/psyc/psyc.conf.in b/src/psyc/psyc.conf.in
index 461552698..4a4a96954 100644
--- a/src/psyc/psyc.conf.in
+++ b/src/psyc/psyc.conf.in
@@ -1,8 +1,12 @@
[psyc]
AUTOSTART = @AUTOSTART@
BINARY = gnunet-service-psyc
+
UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-psyc.sock
-UNIX_MATCH_UID = NO
+UNIX_MATCH_UID = YES
UNIX_MATCH_GID = YES
+
@UNIXONLY@PORT = 2115
-HOSTNAME = localhost \ No newline at end of file
+HOSTNAME = localhost
+ACCEPT_FROM = 127.0.0.1;
+ACCEPT_FROM6 = ::1;
diff --git a/src/psyc/test_psyc.conf b/src/psyc/test_psyc.conf
index 70a408ae3..8eb0019a9 100644
--- a/src/psyc/test_psyc.conf
+++ b/src/psyc/test_psyc.conf
@@ -1,2 +1,2 @@
[arm]
-DEFAULTSERVICES = psyc psycstore multicast
+DEFAULTSERVICES = multicast psycstore psyc
diff --git a/src/psycstore/psycstore.conf.in b/src/psycstore/psycstore.conf.in
index 18c2d1adf..ba8b21753 100644
--- a/src/psycstore/psycstore.conf.in
+++ b/src/psycstore/psycstore.conf.in
@@ -1,11 +1,16 @@
[psycstore]
AUTOSTART = @AUTOSTART@
BINARY = gnunet-service-psycstore
+
UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-psycstore.sock
-HOSTNAME = localhost
-@UNIXONLY@PORT = 2111
-UNIX_MATCH_UID = NO
+UNIX_MATCH_UID = YES
UNIX_MATCH_GID = YES
+
+@UNIXONLY@PORT = 2111
+HOSTNAME = localhost
+ACCEPT_FROM = 127.0.0.1;
+ACCEPT_FROM6 = ::1;
+
DATABASE = sqlite
[psycstore-sqlite]
diff --git a/src/social/Makefile.am b/src/social/Makefile.am
new file mode 100644
index 000000000..04184dbc6
--- /dev/null
+++ b/src/social/Makefile.am
@@ -0,0 +1,78 @@
+AM_CPPFLAGS = -I$(top_srcdir)/src/include
+
+pkgcfgdir= $(pkgdatadir)/config.d/
+
+libexecdir= $(pkglibdir)/libexec/
+
+pkgcfg_DATA = \
+ social.conf
+
+
+if MINGW
+ WINFLAGS = -Wl,--no-undefined -Wl,--export-all-symbols
+endif
+
+if USE_COVERAGE
+ AM_CFLAGS = --coverage -O0
+ XLIB = -lgcov
+endif
+
+lib_LTLIBRARIES = libgnunetsocial.la
+
+libgnunetsocial_la_SOURCES = \
+ social_api.c social.h
+libgnunetsocial_la_LIBADD = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/env/libgnunetenv.la \
+ $(GN_LIBINTL) $(XLIB)
+libgnunetsocial_la_LDFLAGS = \
+ $(GN_LIB_LDFLAGS) $(WINFLAGS) \
+ -version-info 0:0:0
+libgnunetsocial_la_DEPENDENCIES = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/env/libgnunetenv.la
+
+bin_PROGRAMS =
+
+libexec_PROGRAMS = \
+ gnunet-service-social
+
+gnunet_service_social_SOURCES = \
+ gnunet-service-social.c
+gnunet_service_social_LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/statistics/libgnunetstatistics.la \
+ $(top_builddir)/src/psyc/libgnunetpsyc.la \
+ $(GN_LIBINTL)
+gnunet_service_social_DEPENDENCIES = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/statistics/libgnunetstatistics.la \
+ $(top_builddir)/src/psyc/libgnunetpsyc.la
+gnunet_service_social_CFLAGS = $(AM_CFLAGS)
+
+
+if HAVE_TESTING
+check_PROGRAMS = \
+ test_social
+endif
+
+if ENABLE_TEST_RUN
+AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH;
+TESTS = $(check_PROGRAMS)
+endif
+
+test_social_SOURCES = \
+ test_social.c
+test_social_LDADD = \
+ libgnunetsocial.la \
+ $(top_builddir)/src/testing/libgnunettesting.la \
+ $(top_builddir)/src/env/libgnunetenv.la \
+ $(top_builddir)/src/util/libgnunetutil.la
+test_social_DEPENDENCIES = \
+ libgnunetsocial.la \
+ $(top_builddir)/src/testing/libgnunettesting.la \
+ $(top_builddir)/src/env/libgnunetenv.la \
+ $(top_builddir)/src/util/libgnunetutil.la
+
+EXTRA_DIST = \
+ test_social.conf
diff --git a/src/social/gnunet-service-social.c b/src/social/gnunet-service-social.c
new file mode 100644
index 000000000..db704898b
--- /dev/null
+++ b/src/social/gnunet-service-social.c
@@ -0,0 +1,461 @@
+/*
+ * This file is part of GNUnet
+ * (C) 2013 Christian Grothoff (and other contributing authors)
+ *
+ * GNUnet is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 3, or (at your
+ * option) any later version.
+ *
+ * GNUnet is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNUnet; see the file COPYING. If not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/**
+ * @file psyc/gnunet-service-social.c
+ * @brief Social service
+ * @author Gabor X Toth
+ */
+
+#include <inttypes.h>
+
+#include "platform.h"
+#include "gnunet_util_lib.h"
+#include "gnunet_constants.h"
+#include "gnunet_protocols.h"
+#include "gnunet_statistics_service.h"
+#include "gnunet_psyc_service.h"
+#include "gnunet_social_service.h"
+#include "social.h"
+
+
+/**
+ * Handle to our current configuration.
+ */
+static const struct GNUNET_CONFIGURATION_Handle *cfg;
+
+/**
+ * Handle to the statistics service.
+ */
+static struct GNUNET_STATISTICS_Handle *stats;
+
+/**
+ * Notification context, simplifies client broadcasts.
+ */
+static struct GNUNET_SERVER_NotificationContext *nc;
+
+/**
+ * All connected hosts.
+ * Place's pub_key_hash -> struct Host
+ */
+static struct GNUNET_CONTAINER_MultiHashMap *hosts;
+
+/**
+ * All connected guests.
+ * Place's pub_key_hash -> struct Guest
+ */
+static struct GNUNET_CONTAINER_MultiHashMap *guests;
+
+/**
+ * Connected guests per place.
+ * Place's pub_key_hash -> Guest's pub_key -> struct Guest
+ */
+static struct GNUNET_CONTAINER_MultiHashMap *place_guests;
+
+
+/**
+ * Message in the transmission queue.
+ */
+struct TransmitMessage
+{
+ struct TransmitMessage *prev;
+ struct TransmitMessage *next;
+
+ struct GNUNET_SERVER_Client *client;
+
+ /**
+ * ID assigned to the message.
+ */
+ uint64_t id;
+
+ /**
+ * Size of @a buf
+ */
+ uint16_t size;
+
+ /**
+ * @see enum MessageState
+ */
+ uint8_t state;
+
+ /* Followed by message */
+};
+
+
+/**
+ * List of connected clients.
+ */
+struct ClientList
+{
+ struct ClientList *prev;
+ struct ClientList *next;
+ struct GNUNET_SERVER_Client *client;
+};
+
+
+/**
+ * Common part of the client context for both a host and guest.
+ */
+struct Place
+{
+ struct ClientList *clients_head;
+ struct ClientList *clients_tail;
+
+ struct TransmitMessage *tmit_head;
+ struct TransmitMessage *tmit_tail;
+
+ /**
+ * Public key of the channel.
+ */
+ struct GNUNET_CRYPTO_EddsaPublicKey pub_key;
+
+ /**
+ * Hash of @a pub_key.
+ */
+ struct GNUNET_HashCode pub_key_hash;
+
+ /**
+ * Is this a host (#GNUNET_YES), or guest (#GNUNET_NO)?
+ */
+ uint8_t is_host;
+};
+
+
+/**
+ * Client context for a host.
+ */
+struct Host
+{
+ /**
+ * Place struct common for Host and Guest
+ */
+ struct Place pl;
+
+ /**
+ * Private key of the channel.
+ */
+ struct GNUNET_CRYPTO_EddsaPrivateKey priv_key;
+
+ /**
+ * Handle for the multicast origin.
+ */
+ struct GNUNET_PSYC_Master *master;
+
+ /**
+ * Transmit handle for multicast.
+ */
+ struct GNUNET_PSYC_MasterTransmitHandle *tmit_handle;
+
+ /**
+ * Incoming join requests.
+ * guest_key -> struct GNUNET_PSYC_JoinHandle *
+ */
+ struct GNUNET_CONTAINER_MultiHashMap *join_reqs;
+
+ /**
+ * @see enum GNUNET_PSYC_Policy
+ */
+ enum GNUNET_PSYC_Policy policy;
+};
+
+
+/**
+ * Client context for a guest.
+ */
+struct Guest
+{
+ /**
+ * Place struct common for Host and Guest.
+ */
+ struct Place pl;
+
+ /**
+ * Private key of the slave.
+ */
+ struct GNUNET_CRYPTO_EddsaPrivateKey priv_key;
+
+ /**
+ * Public key of the slave.
+ */
+ struct GNUNET_CRYPTO_EddsaPublicKey pub_key;
+
+ /**
+ * Hash of @a pub_key.
+ */
+ struct GNUNET_HashCode pub_key_hash;
+
+ /**
+ * Handle for the PSYC slave.
+ */
+ struct GNUNET_PSYC_Slave *slave;
+
+ /**
+ * Transmit handle for multicast.
+ */
+ struct GNUNET_PSYC_SlaveTransmitHandle *tmit_handle;
+
+ /**
+ * Peer identity of the origin.
+ */
+ struct GNUNET_PeerIdentity origin;
+
+ /**
+ * Number of items in @a relays.
+ */
+ uint32_t relay_count;
+
+ /**
+ * Relays that multicast can use to connect.
+ */
+ struct GNUNET_PeerIdentity *relays;
+
+ /**
+ * Join request to be transmitted to the master on join.
+ */
+ struct GNUNET_MessageHeader *join_req;
+};
+
+
+static inline void
+transmit_message (struct Place *pl);
+
+
+/**
+ * Task run during shutdown.
+ *
+ * @param cls unused
+ * @param tc unused
+ */
+static void
+shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ if (NULL != nc)
+ {
+ GNUNET_SERVER_notification_context_destroy (nc);
+ nc = NULL;
+ }
+ if (NULL != stats)
+ {
+ GNUNET_STATISTICS_destroy (stats, GNUNET_YES);
+ stats = NULL;
+ }
+}
+
+
+/**
+ * Clean up host data structures after a client disconnected.
+ */
+static void
+cleanup_host (struct Host *hst)
+{
+ struct Place *pl = &hst->pl;
+
+ if (NULL != hst->master)
+ GNUNET_PSYC_master_stop (hst->master);
+ GNUNET_CONTAINER_multihashmap_destroy (hst->join_reqs);
+ GNUNET_CONTAINER_multihashmap_remove (hosts, &pl->pub_key_hash, pl);
+}
+
+
+/**
+ * Clean up guest data structures after a client disconnected.
+ */
+static void
+cleanup_guest (struct Guest *gst)
+{
+ struct Place *pl = &gst->pl;
+ struct GNUNET_CONTAINER_MultiHashMap *
+ pl_gst = GNUNET_CONTAINER_multihashmap_get (place_guests,
+ &pl->pub_key_hash);
+ GNUNET_assert (NULL != pl_gst);
+ GNUNET_CONTAINER_multihashmap_remove (pl_gst, &gst->pub_key_hash, gst);
+
+ if (0 == GNUNET_CONTAINER_multihashmap_size (pl_gst))
+ {
+ GNUNET_CONTAINER_multihashmap_remove (place_guests, &pl->pub_key_hash,
+ pl_gst);
+ GNUNET_CONTAINER_multihashmap_destroy (pl_gst);
+ }
+ GNUNET_CONTAINER_multihashmap_remove (guests, &pl->pub_key_hash, gst);
+
+ if (NULL != gst->join_req)
+ GNUNET_free (gst->join_req);
+ if (NULL != gst->relays)
+ GNUNET_free (gst->relays);
+ if (NULL != gst->slave)
+ GNUNET_PSYC_slave_part (gst->slave);
+ GNUNET_CONTAINER_multihashmap_remove (guests, &pl->pub_key_hash, pl);
+}
+
+
+/**
+ * Clean up place data structures after a client disconnected.
+ */
+static void
+cleanup_place (struct Place *pl)
+{
+ (GNUNET_YES == pl->is_host)
+ ? cleanup_host ((struct Host *) pl)
+ : cleanup_guest ((struct Guest *) pl);
+ GNUNET_free (pl);
+}
+
+
+/**
+ * Called whenever a client is disconnected.
+ * Frees our resources associated with that client.
+ *
+ * @param cls Closure.
+ * @param client Identification of the client.
+ */
+static void
+client_disconnect (void *cls, struct GNUNET_SERVER_Client *client)
+{
+ if (NULL == client)
+ return;
+
+ struct Place *
+ pl = GNUNET_SERVER_client_get_user_context (client, struct Place);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "%p Client (%s) disconnected from place %s\n",
+ pl, (GNUNET_YES == pl->is_host) ? "host" : "guest",
+ GNUNET_h2s (&pl->pub_key_hash));
+
+ if (NULL == pl)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "%p User context is NULL in client_disconnect()\n", pl);
+ GNUNET_break (0);
+ return;
+ }
+
+ struct ClientList *cl = pl->clients_head;
+ while (NULL != cl)
+ {
+ if (cl->client == client)
+ {
+ GNUNET_CONTAINER_DLL_remove (pl->clients_head, pl->clients_tail, cl);
+ GNUNET_free (cl);
+ break;
+ }
+ cl = cl->next;
+ }
+
+ if (NULL == pl->clients_head)
+ { /* Last client disconnected. */
+ if (NULL != pl->tmit_head)
+ { /* Send pending messages to PSYC before cleanup. */
+ //FIXME: transmit_message (pl);
+ }
+ else
+ {
+ cleanup_place (pl);
+ }
+ }
+}
+
+
+static void
+client_home_enter (void *cls, struct GNUNET_SERVER_Client *client,
+ const struct GNUNET_MessageHeader *msg)
+{
+
+}
+
+
+static void
+client_place_enter (void *cls, struct GNUNET_SERVER_Client *client,
+ const struct GNUNET_MessageHeader *msg)
+{
+
+}
+
+
+static void
+client_join_decision (void *cls, struct GNUNET_SERVER_Client *client,
+ const struct GNUNET_MessageHeader *msg)
+{
+
+}
+
+
+static void
+client_psyc_message (void *cls, struct GNUNET_SERVER_Client *client,
+ const struct GNUNET_MessageHeader *msg)
+{
+
+}
+
+
+/**
+ * Initialize the PSYC service.
+ *
+ * @param cls Closure.
+ * @param server The initialized server.
+ * @param c Configuration to use.
+ */
+static void
+run (void *cls, struct GNUNET_SERVER_Handle *server,
+ const struct GNUNET_CONFIGURATION_Handle *c)
+{
+ static const struct GNUNET_SERVER_MessageHandler handlers[] = {
+ { &client_home_enter, NULL,
+ GNUNET_MESSAGE_TYPE_SOCIAL_HOME_ENTER, 0 },
+
+ { &client_place_enter, NULL,
+ GNUNET_MESSAGE_TYPE_SOCIAL_PLACE_ENTER, 0 },
+
+ { &client_join_decision, NULL,
+ GNUNET_MESSAGE_TYPE_SOCIAL_JOIN_DECISION, 0 },
+
+ { &client_psyc_message, NULL,
+ GNUNET_MESSAGE_TYPE_PSYC_MESSAGE, 0 }
+ };
+
+ cfg = c;
+ stats = GNUNET_STATISTICS_create ("social", cfg);
+ hosts = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_YES);
+ guests = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_YES);
+ place_guests = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_NO);
+ nc = GNUNET_SERVER_notification_context_create (server, 1);
+ GNUNET_SERVER_add_handlers (server, handlers);
+ GNUNET_SERVER_disconnect_notify (server, &client_disconnect, NULL);
+ GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL,
+ &shutdown_task, NULL);
+}
+
+
+/**
+ * The main function for the service.
+ *
+ * @param argc number of arguments from the command line
+ * @param argv command line arguments
+ * @return 0 ok, 1 on error
+ */
+int
+main (int argc, char *const *argv)
+{
+ return (GNUNET_OK ==
+ GNUNET_SERVICE_run (argc, argv, "social",
+ GNUNET_SERVICE_OPTION_NONE,
+ &run, NULL)) ? 0 : 1;
+}
+
+/* end of gnunet-service-social.c */
diff --git a/src/social/social.conf.in b/src/social/social.conf.in
new file mode 100644
index 000000000..e52318bc3
--- /dev/null
+++ b/src/social/social.conf.in
@@ -0,0 +1,12 @@
+[social]
+AUTOSTART = @AUTOSTART@
+BINARY = gnunet-service-social
+
+UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-social.sock
+UNIX_MATCH_UID = YES
+UNIX_MATCH_GID = YES
+
+@UNIXONLY@PORT = 2116
+HOSTNAME = localhost
+ACCEPT_FROM = 127.0.0.1;
+ACCEPT_FROM6 = ::1;
diff --git a/src/social/social.h b/src/social/social.h
new file mode 100644
index 000000000..7f854eed8
--- /dev/null
+++ b/src/social/social.h
@@ -0,0 +1,46 @@
+/*
+ * This file is part of GNUnet
+ * (C) 2013 Christian Grothoff (and other contributing authors)
+ *
+ * GNUnet is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 3, or (at your
+ * option) any later version.
+ *
+ * GNUnet is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNUnet; see the file COPYING. If not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/**
+ * @file psyc/psyc.h
+ * @brief Common type definitions for the Social service and API.
+ * @author Gabor X Toth
+ */
+
+#ifndef SOCIAL_H
+#define SOCIAL_H
+
+#include "platform.h"
+#include "gnunet_social_service.h"
+
+
+GNUNET_NETWORK_STRUCT_BEGIN
+
+/**** library -> service ****/
+
+
+
+/**** service -> library ****/
+
+
+
+GNUNET_NETWORK_STRUCT_END
+
+#endif
diff --git a/src/social/social_api.c b/src/social/social_api.c
new file mode 100644
index 000000000..fd6e8f04a
--- /dev/null
+++ b/src/social/social_api.c
@@ -0,0 +1,627 @@
+/*
+ * This file is part of GNUnet
+ * (C) 2013 Christian Grothoff (and other contributing authors)
+ *
+ * GNUnet is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 3, or (at your
+ * option) any later version.
+ *
+ * GNUnet is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNUnet; see the file COPYING. If not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/**
+ * @file social/social_api.c
+ * @brief Social service; implements social functionality using the PSYC service.
+ * @author Gabor X Toth
+ */
+
+#include <inttypes.h>
+
+#include "platform.h"
+#include "gnunet_util_lib.h"
+#include "gnunet_env_lib.h"
+#include "gnunet_psyc_service.h"
+#include "gnunet_social_service.h"
+#include "social.h"
+
+
+/**
+ * Handle for another user (who is likely pseudonymous) in the network.
+ */
+struct GNUNET_SOCIAL_Nym
+{
+
+};
+
+
+/**
+ * Handle for a place where social interactions happen.
+ */
+struct GNUNET_SOCIAL_Place
+{
+
+};
+
+
+/**
+ * Handle for a place that one of our egos hosts.
+ */
+struct GNUNET_SOCIAL_Home
+{
+
+};
+
+
+/**
+ * Handle to an implementation of try-and-slice.
+ */
+struct GNUNET_SOCIAL_Slicer
+{
+
+};
+
+
+/**
+ * Handle for an announcement request.
+ */
+struct GNUNET_SOCIAL_Announcement
+{
+
+};
+
+
+struct GNUNET_SOCIAL_WatchHandle
+{
+
+};
+
+
+struct GNUNET_SOCIAL_LookHandle
+{
+
+};
+
+
+/**
+ * A talk request.
+ */
+struct GNUNET_SOCIAL_TalkRequest
+{
+
+};
+
+
+/**
+ * A history lesson.
+ */
+struct GNUNET_SOCIAL_HistoryLesson
+{
+
+};
+
+
+/**
+ * Create a try-and-slice instance.
+ *
+ * @return A new try-and-slice construct.
+ */
+struct GNUNET_SOCIAL_Slicer *
+GNUNET_SOCIAL_slicer_create (void)
+{
+ return NULL;
+}
+
+
+/**
+ * Add a method to the try-and-slice instance.
+ *
+ * A slicer processes messages and calls methods that match a message. A match
+ * happens whenever the method name of a message starts with the method_name
+ * parameter given here.
+ *
+ * @param slicer The try-and-slice instance to extend.
+ * @param method_name Name of the given method, use empty string for default.
+ * @param method Method to invoke.
+ * @param method_cls Closure for method.
+ */
+void
+GNUNET_SOCIAL_slicer_add (struct GNUNET_SOCIAL_Slicer *slicer,
+ const char *method_name,
+ GNUNET_SOCIAL_Method method,
+ void *method_cls)
+{
+
+}
+
+
+/**
+ * Remove a registered method from the try-and-slice instance.
+ *
+ * @param slicer The try-and-slice instance.
+ * @param method_name Name of the method to remove.
+ * @param method Method handler.
+ */
+void
+GNUNET_SOCIAL_slicer_remove (struct GNUNET_SOCIAL_Slicer *slicer,
+ const char *method_name,
+ GNUNET_SOCIAL_Method method)
+{
+
+}
+
+
+/**
+ * Destroy a given try-and-slice instance.
+ *
+ * @param slicer slicer to destroy
+ */
+void
+GNUNET_SOCIAL_slicer_destroy (struct GNUNET_SOCIAL_Slicer *slicer)
+{
+
+}
+
+
+/**
+ * Enter a home where guests (nyms) can be hosted.
+ *
+ * A home is created upon first entering, and exists until
+ * GNUNET_SOCIAL_home_destroy() is called. It can also be left temporarily using
+ * GNUNET_SOCIAL_home_leave().
+ *
+ * @param cfg Configuration to contact the social service.
+ * @param home_keyfile File with the private-public key pair of the home,
+ * created if the file does not exist; pass NULL for ephemeral homes.
+ * @param policy Policy specifying entry and history restrictions of the home.
+ * @param ego Owner of the home (host).
+ * @param slicer Slicer to handle guests talking.
+ * @param listener_cb Function to handle new nyms that want to enter.
+ * @param farewell_cb Function to handle departing nyms.
+ * @param cls Closure for @a listener_cb and @a farewell_cb.
+ * @return Handle for a new home.
+ */
+struct GNUNET_SOCIAL_Home *
+GNUNET_SOCIAL_home_enter (const struct GNUNET_CONFIGURATION_Handle *cfg,
+ const char *home_keyfile,
+ enum GNUNET_PSYC_Policy policy,
+ struct GNUNET_IDENTITY_Ego *ego,
+ struct GNUNET_SOCIAL_Slicer *slicer,
+ GNUNET_SOCIAL_AnswerDoorCallback listener_cb,
+ GNUNET_SOCIAL_FarewellCallback farewell_cb,
+ void *cls)
+{
+ return NULL;
+}
+
+
+/**
+ * Admit @a nym to the @a home.
+ *
+ * The @a nym reference will remain valid until either the home is destroyed or
+ * @a nym leaves.
+ *
+ * @param home Home to allow @a nym to enter.
+ * @param nym Handle for the entity that wants to enter.
+ */
+void
+GNUNET_SOCIAL_home_admit (struct GNUNET_SOCIAL_Home *home,
+ struct GNUNET_SOCIAL_Nym *nym)
+{
+
+}
+
+
+/**
+ * Throw @a nym out of the @a home.
+ *
+ * The @a nym reference will remain valid until the
+ * #GNUNET_SOCIAL_FarewellCallback is invoked,
+ * which should be very soon after this call.
+ *
+ * @param home Home to eject @a nym from.
+ * @param nym Handle for the entity to be ejected.
+ */
+void
+GNUNET_SOCIAL_home_eject (struct GNUNET_SOCIAL_Home *home,
+ struct GNUNET_SOCIAL_Nym *nym)
+{
+
+}
+
+
+/**
+ * Refuse @a nym entry into the @a home.
+ *
+ * @param home Home to disallow @a nym to enter.
+ * @param nym Handle for the entity that wanted to enter.
+ * @param method_name Method name for the rejection message.
+ * @param env Environment containing variables for the message, or NULL.
+ * @param data Data for the rejection message to send back.
+ * @param data_size Number of bytes in @a data for method.
+ */
+void
+GNUNET_SOCIAL_home_reject_entry (struct GNUNET_SOCIAL_Home *home,
+ struct GNUNET_SOCIAL_Nym *nym,
+ const char *method_name,
+ const struct GNUNET_ENV_Environment *env,
+ const void *data,
+ size_t data_size)
+{
+
+}
+
+
+/**
+ * Get the public key of a nym.
+ *
+ * Suitable, for example, to be used with GNUNET_NAMESTORE_zone_to_name().
+ *
+ * @param nym Pseudonym to map to a cryptographic identifier.
+ * @param[out] nym_key Set to the public key of the nym.
+ */
+void
+GNUNET_SOCIAL_nym_get_key (struct GNUNET_SOCIAL_Nym *nym,
+ struct GNUNET_CRYPTO_EddsaPublicKey *nym_key)
+{
+
+}
+
+
+/**
+ * Obtain the private-public key pair of the home.
+ *
+ * @param home Home to get the key of.
+ * @param[out] home_key Set to the private-public key pair of the home. The public part is suitable for storing in GNS within a "PLACE" record, along with peer IDs to join at.
+ */
+void
+GNUNET_SOCIAL_home_get_key (struct GNUNET_SOCIAL_Home *home,
+ struct GNUNET_CRYPTO_EddsaPrivateKey *home_key)
+{
+
+}
+
+
+/**
+ * Advertise @a home under @a name in the GNS zone of the @e ego.
+ *
+ * @param home The home to advertise.
+ * @param name The name for the PLACE record to put in the zone.
+ * @param peer_count Number of elements in the @a peers array.
+ * @param peers List of peers in the PLACE record that can be used to send join
+ * requests to.
+ * @param expiration_time Expiration time of the record, use 0 to remove the record.
+ * @param password Password used to encrypt the record.
+ */
+void
+GNUNET_SOCIAL_home_advertise (struct GNUNET_SOCIAL_Home *home,
+ const char *name,
+ size_t peer_count,
+ const struct GNUNET_PeerIdentity *peers,
+ struct GNUNET_TIME_Relative expiration_time,
+ const char *password)
+{
+
+}
+
+
+/**
+ * Send a message to all nyms that are present in the home.
+ *
+ * This function is restricted to the home owner. Nyms can only send requests
+ * to the home owner who can decide to relay it to other guests.
+ *
+ * @param home Home to address the announcement to.
+ * @param method_name Method to use for the announcement.
+ * @param env Environment containing variables for the message and operations on
+ * objects of the home, or NULL.
+ * @param notify Function to call to get the payload of the announcement.
+ * @param notify_cls Closure for @a notify.
+ * @param flags Flags for this announcement.
+ * @return NULL on error (announcement already in progress?).
+ */
+struct GNUNET_SOCIAL_Announcement *
+GNUNET_SOCIAL_home_announce (struct GNUNET_SOCIAL_Home *home,
+ const char *method_name,
+ const struct GNUNET_ENV_Environment *env,
+ GNUNET_CONNECTION_TransmitReadyNotify notify,
+ void *notify_cls,
+ enum GNUNET_SOCIAL_AnnounceFlags flags)
+{
+ return NULL;
+}
+
+
+/**
+ * Cancel announcement.
+ *
+ * @param a The announcement to cancel.
+ */
+void
+GNUNET_SOCIAL_home_announce_cancel (struct GNUNET_SOCIAL_Announcement *a)
+{
+
+}
+
+
+/**
+ * Convert our home to a place so we can access it via the place API.
+ *
+ * @param home Handle for the home.
+ * @return Place handle for the same home, valid as long as @a home is valid;
+ * do NOT try to GNUNET_SOCIAL_place_leave() this place, it's your home!
+ */
+struct GNUNET_SOCIAL_Place *
+GNUNET_SOCIAL_home_get_place (struct GNUNET_SOCIAL_Home *home)
+{
+ return NULL;
+}
+
+
+/**
+ * Leave a home.
+
+ * Invalidates home handle.
+ * Guests will be disconnected until the home is restarted.
+ *
+ * @param home Home to leave.
+ * @param keep_active Keep home active after last application disconnected.
+ */
+void
+GNUNET_SOCIAL_home_leave (struct GNUNET_SOCIAL_Home *home, int keep_active)
+{
+
+}
+
+/**
+ * Request entry to a place (home hosted by someone else).
+ *
+ * @param cfg Configuration to contact the social service.
+ * @param ego Owner of the home (host).
+ * @param address GNS name of the place to enter. Either in the form of
+ * 'room.friend.gnu', or 'NYMPUBKEY.zkey'. This latter case refers to
+ * the 'PLACE' record of the empty label ("+") in the GNS zone with the
+ * nym's public key 'NYMPUBKEY', and can be used to request entry to a
+ * pseudonym's place directly.
+ * @param method_name Method name for the message.
+ * @param env Environment containing variables for the message, or NULL.
+ * @param data Payload for the message to give to the enter callback.
+ * @param data_size Number of bytes in @a data.
+ * @param slicer Slicer to use for processing incoming requests from guests.
+ * @return NULL on errors, otherwise handle to the place.
+ */
+struct GNUNET_SOCIAL_Place *
+GNUNET_SOCIAL_place_enter (const struct GNUNET_CONFIGURATION_Handle *cfg,
+ struct GNUNET_IDENTITY_Ego *ego,
+ char *address,
+ const char *method_name,
+ const struct GNUNET_ENV_Environment *env,
+ const void *data,
+ size_t data_size,
+ struct GNUNET_SOCIAL_Slicer *slicer)
+{
+ return NULL;
+}
+
+/**
+ * Request entry to a place (home hosted by someone else).
+ *
+ * @param cfg Configuration to contact the social service.
+ * @param ego Owner of the home (host).
+ * @param crypto_address Public key of the place to enter.
+ * @param origin Peer identity of the origin of the underlying multicast group.
+ * @param relay_count Number of elements in the @a relays array.
+ * @param relays Relays for the underlying multicast group.
+ * @param method_name Method name for the message.
+ * @param env Environment containing variables for the message, or NULL.
+ * @param data Payload for the message to give to the enter callback.
+ * @param data_size Number of bytes in @a data.
+ * @param slicer Slicer to use for processing incoming requests from guests.
+ * @return NULL on errors, otherwise handle to the place.
+ */
+struct GNUNET_SOCIAL_Place *
+GNUNET_SOCIAL_place_enter2 (const struct GNUNET_CONFIGURATION_Handle *cfg,
+ struct GNUNET_IDENTITY_Ego *ego,
+ struct GNUNET_CRYPTO_EddsaPublicKey *crypto_address,
+ struct GNUNET_PeerIdentity *origin,
+ size_t relay_count,
+ struct GNUNET_PeerIdentity *relays,
+ const char *method_name,
+ const struct GNUNET_ENV_Environment *env,
+ const void *data,
+ size_t data_size,
+ struct GNUNET_SOCIAL_Slicer *slicer)
+{
+ return NULL;
+}
+
+
+/**
+ * Watch a place for changed objects.
+ *
+ * @param place Place to watch.
+ * @param object_filter Object prefix to match.
+ * @param state_cb Function to call when an object/state changes.
+ * @param state_cb_cls Closure for callback.
+ *
+ * @return Handle that can be used to cancel watching.
+ */
+struct GNUNET_SOCIAL_WatchHandle *
+GNUNET_SOCIAL_place_watch (struct GNUNET_SOCIAL_Place *place,
+ const char *object_filter,
+ GNUNET_PSYC_StateCallback state_cb,
+ void *state_cb_cls)
+{
+ return NULL;
+}
+
+
+/**
+ * Cancel watching a place for changed objects.
+ *
+ * @param wh Watch handle to cancel.
+ */
+void
+GNUNET_SOCIAL_place_watch_cancel (struct GNUNET_SOCIAL_WatchHandle *wh)
+{
+
+}
+
+
+/**
+ * Look at objects in the place with a matching name prefix.
+ *
+ * @param place The place to look its objects at.
+ * @param name_prefix Look at objects with names beginning with this value.
+ * @param state_cb Function to call for each object found.
+ * @param state_cb_cls Closure for callback function.
+ *
+ * @return Handle that can be used to stop looking at objects.
+ */
+struct GNUNET_SOCIAL_LookHandle *
+GNUNET_SOCIAL_place_look (struct GNUNET_SOCIAL_Place *place,
+ const char *name_prefix,
+ GNUNET_PSYC_StateCallback state_cb,
+ void *state_cb_cls)
+{
+ return NULL;
+}
+
+
+/**
+ * Stop looking at objects.
+ *
+ * @param lh Look handle to stop.
+ */
+void
+GNUNET_SOCIAL_place_look_cancel (struct GNUNET_SOCIAL_LookHandle *lh)
+{
+
+}
+
+
+
+/**
+ * Look at a particular object in the place.
+ *
+ * The best matching object is returned (its name might be less specific than
+ * what was requested).
+ *
+ * @param place The place to look the object at.
+ * @param full_name Full name of the object.
+ * @param value_size Set to the size of the returned value.
+ * @return NULL if there is no such object at this place.
+ */
+const void *
+GNUNET_SOCIAL_place_look_at (struct GNUNET_SOCIAL_Place *place,
+ const char *full_name,
+ size_t *value_size)
+{
+ return NULL;
+}
+
+
+/**
+ * Talk to the host of the place.
+ *
+ * @param place Place where we want to talk to the host.
+ * @param method_name Method to invoke on the host.
+ * @param env Environment containing variables for the message, or NULL.
+ * @param notify Function to use to get the payload for the method.
+ * @param notify_cls Closure for @a notify.
+ * @param flags Flags for the message being sent.
+ * @return NULL if we are already trying to talk to the host,
+ * otherwise handle to cancel the request.
+ */
+struct GNUNET_SOCIAL_TalkRequest *
+GNUNET_SOCIAL_place_talk (struct GNUNET_SOCIAL_Place *place,
+ const char *method_name,
+ const struct GNUNET_ENV_Environment *env,
+ GNUNET_CONNECTION_TransmitReadyNotify notify,
+ void *notify_cls,
+ enum GNUNET_SOCIAL_TalkFlags flags)
+{
+ return NULL;
+}
+
+
+/**
+ * Cancel talking to the host of the place.
+ *
+ * @param tr Talk request to cancel.
+ */
+void
+GNUNET_SOCIAL_place_talk_cancel (struct GNUNET_SOCIAL_TalkRequest *tr)
+{
+
+}
+
+
+/**
+ * Learn about the history of a place.
+ *
+ * Sends messages through the slicer function of the place where
+ * start_message_id <= message_id <= end_message_id.
+ * The messages will have the #GNUNET_PSYC_MESSAGE_HISTORIC flag set.
+ *
+ * To get the latest message, use 0 for both the start and end message ID.
+ *
+ * @param place Place we want to learn more about.
+ * @param start_message_id First historic message we are interested in.
+ * @param end_message_id Last historic message we are interested in (inclusive).
+ * @param slicer Slicer to use to process history. Can be the same as the
+ * slicer of the place, as the HISTORIC flag allows distinguishing
+ * old messages from fresh ones.
+ * @param finish_cb Function called after the last message in the history lesson
+ * is passed through the @a slicer. NULL if not needed.
+ * @param finish_cb_cls Closure for @a finish_cb.
+ * @return Handle to abort history lesson, never NULL (multiple lessons
+ * at the same time are allowed).
+ */
+struct GNUNET_SOCIAL_HistoryLesson *
+GNUNET_SOCIAL_place_get_history (struct GNUNET_SOCIAL_Place *place,
+ uint64_t start_message_id,
+ uint64_t end_message_id,
+ const struct GNUNET_SOCIAL_Slicer *slicer,
+ void (*finish_cb)(void *),
+ void *finish_cb_cls)
+{
+ return NULL;
+}
+
+
+/**
+ * Stop processing messages from the history lesson.
+ *
+ * Must not be called after the finish callback of the history lesson is called.
+ *
+ * @param hist History lesson to cancel.
+ */
+void
+GNUNET_SOCIAL_place_get_history_cancel (struct GNUNET_SOCIAL_HistoryLesson *hist)
+{
+
+}
+
+
+/**
+ * Leave a place permanently.
+ *
+ * Notifies the owner of the place about leaving, and destroys the place handle.
+ *
+ * @param place Place to leave permanently.
+ * @param keep_active Keep place active after last application disconnected.
+ */
+void
+GNUNET_SOCIAL_place_leave (struct GNUNET_SOCIAL_Place *place, int keep_active)
+{
+
+}
diff --git a/src/social/test_social.c b/src/social/test_social.c
new file mode 100644
index 000000000..8851ba0df
--- /dev/null
+++ b/src/social/test_social.c
@@ -0,0 +1,158 @@
+/*
+ * This file is part of GNUnet
+ * (C) 2013 Christian Grothoff (and other contributing authors)
+ *
+ * GNUnet is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 3, or (at your
+ * option) any later version.
+ *
+ * GNUnet is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNUnet; see the file COPYING. If not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/**
+ * @file social/test_social.c
+ * @brief Test for the SOCIAL service.
+ * @author Gabor X Toth
+ * @author Christian Grothoff
+ */
+
+#include <inttypes.h>
+
+#include "platform.h"
+#include "gnunet_crypto_lib.h"
+#include "gnunet_common.h"
+#include "gnunet_util_lib.h"
+#include "gnunet_testing_lib.h"
+#include "gnunet_env_lib.h"
+#include "gnunet_social_service.h"
+
+#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30)
+
+#define DEBUG_SERVICE 0
+
+/**
+ * Return value from 'main'.
+ */
+static int res;
+
+static const struct GNUNET_CONFIGURATION_Handle *cfg;
+
+/**
+ * Handle for task for timeout termination.
+ */
+static GNUNET_SCHEDULER_TaskIdentifier end_badly_task;
+
+
+/**
+ * Clean up all resources used.
+ */
+static void
+cleanup ()
+{
+
+}
+
+
+/**
+ * Terminate the test case (failure).
+ *
+ * @param cls NULL
+ * @param tc scheduler context
+ */
+static void
+end_badly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ res = 1;
+ cleanup ();
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Test FAILED.\n");
+}
+
+
+/**
+ * Terminate the test case (success).
+ *
+ * @param cls NULL
+ * @param tc scheduler context
+ */
+static void
+end_normally (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ res = 0;
+ cleanup ();
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Test PASSED.\n");
+}
+
+
+/**
+ * Finish the test case (successfully).
+ */
+static void
+end ()
+{
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Ending tests.\n");
+
+ if (end_badly_task != GNUNET_SCHEDULER_NO_TASK)
+ {
+ GNUNET_SCHEDULER_cancel (end_badly_task);
+ end_badly_task = GNUNET_SCHEDULER_NO_TASK;
+ }
+ GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MILLISECONDS,
+ &end_normally, NULL);
+}
+
+
+/**
+ * Main function of the test, run from scheduler.
+ *
+ * @param cls NULL
+ * @param cfg configuration we use (also to connect to SOCIAL service)
+ * @param peer handle to access more of the peer (not used)
+ */
+static void
+#if DEBUG_SERVICE
+run (void *cls, char *const *args, const char *cfgfile,
+ const struct GNUNET_CONFIGURATION_Handle *c)
+#else
+run (void *cls,
+ const struct GNUNET_CONFIGURATION_Handle *c,
+ struct GNUNET_TESTING_Peer *peer)
+#endif
+{
+ cfg = c;
+ end_badly_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_badly, NULL);
+
+ /* FIXME: add tests */
+
+ end ();
+}
+
+
+int
+main (int argc, char *argv[])
+{
+ res = 1;
+#if DEBUG_SERVICE
+ const struct GNUNET_GETOPT_CommandLineOption opts[] = {
+ GNUNET_GETOPT_OPTION_END
+ };
+ if (GNUNET_OK != GNUNET_PROGRAM_run (argc, argv, "test-social",
+ "test-social [options]",
+ opts, &run, NULL))
+ return 1;
+#else
+ if (0 != GNUNET_TESTING_peer_run ("test-social", "test_social.conf", &run, NULL))
+ return 1;
+#endif
+ return res;
+}
+
+/* end of test_social.c */
diff --git a/src/social/test_social.conf b/src/social/test_social.conf
new file mode 100644
index 000000000..58c731168
--- /dev/null
+++ b/src/social/test_social.conf
@@ -0,0 +1,2 @@
+[arm]
+DEFAULTSERVICES = multicast psycstore psyc social