/** * Handler for START message from client, sends information * about all identities to the client immediately and * adds the client to the notification context for future * updates. * * @param cls unused * @param client who sent the message * @param message the message received */ static void handle_start_message (void *cls, struct GNUNET_SERVER_Client *client, const struct GNUNET_MessageHeader *message) { struct GNUNET_IDENTITY_UpdateMessage *um; struct GNUNET_IDENTITY_UpdateMessage ume; struct Ego *ego; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received START message from client\n"); GNUNET_SERVER_notification_context_add (nc, client); for (ego = ego_head; NULL != ego; ego = ego->next) { um = create_update_message (ego); GNUNET_SERVER_notification_context_unicast (nc, client, &um->header, GNUNET_NO); GNUNET_free (um); } memset (&ume, 0, sizeof (ume)); ume.header.type = htons (GNUNET_MESSAGE_TYPE_IDENTITY_UPDATE); ume.header.size = htons (sizeof (struct GNUNET_IDENTITY_UpdateMessage)); ume.end_of_list = htons (GNUNET_YES); ume.name_len = htons (0); GNUNET_SERVER_notification_context_unicast (nc, client, &ume.header, GNUNET_NO); GNUNET_SERVER_receive_done (client, GNUNET_OK); }
/** * Handle NOTIFY-message. * * @param cls closure * @param client identification of the client * @param message the actual message */ static void handle_notify (void *cls, struct GNUNET_SERVER_Client *client, const struct GNUNET_MessageHeader *message) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "`%s' message received\n", "NOTIFY"); GNUNET_SERVER_client_mark_monitor (client); GNUNET_SERVER_notification_context_add (notify_list, client); GNUNET_CONTAINER_multihashmap_iterate (hostmap, &do_notify_entry, client); GNUNET_SERVER_receive_done (client, GNUNET_OK); }
/** * Handle SEARCH message. * * @param cls closure * @param client identification of the client * @param message the actual message */ static void handle_search (void *cls, struct GNUNET_SERVER_Client *client, const struct GNUNET_MessageHeader *message) { const struct RegexSearchMessage *sm; const char *string; struct ClientEntry *ce; uint16_t size; size = ntohs (message->size); sm = (const struct RegexSearchMessage *) message; string = (const char *) &sm[1]; if ( (size <= sizeof (struct RegexSearchMessage)) || ('\0' != string[size - sizeof (struct RegexSearchMessage) - 1]) ) { GNUNET_break (0); GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); return; } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting to search for `%s'\n", string); ce = GNUNET_new (struct ClientEntry); ce->client = client; ce->sh = REGEX_INTERNAL_search (dht, string, &handle_search_result, ce, stats); if (NULL == ce->sh) { GNUNET_break (0); GNUNET_free (ce); GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); return; } GNUNET_CONTAINER_DLL_insert (client_head, client_tail, ce); GNUNET_SERVER_notification_context_add (nc, client); GNUNET_SERVER_receive_done (client, GNUNET_OK); }
/** * Setup a new monitoring client using the given server client handle and * the peer identity. * * @param client server's client handle to create our internal handle for * @param peer identity of the peer to monitor the addresses of, * zero to monitor all neighrours. * @return handle to the new monitoring client */ static struct MonitoringClient * setup_val_monitoring_client (struct GNUNET_SERVER_Client *client, struct GNUNET_PeerIdentity *peer) { struct MonitoringClient *mc; static struct GNUNET_PeerIdentity all_zeros; GNUNET_assert (lookup_monitoring_client (val_monitoring_clients_head, client) == NULL); mc = GNUNET_new (struct MonitoringClient); mc->client = client; mc->peer = *peer; GNUNET_CONTAINER_DLL_insert (val_monitoring_clients_head, val_monitoring_clients_tail, mc); GNUNET_SERVER_notification_context_add (val_nc, client); if (0 != memcmp (peer, &all_zeros, sizeof (struct GNUNET_PeerIdentity))) GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Client %p started monitoring of the peer `%s'\n", mc, GNUNET_i2s (peer)); else GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Client %p started monitoring all peers\n", mc); return mc; }
/** * Handle lookup requests from client * * @param cls the closure * @param client the client * @param message the message */ static void handle_lookup(void *cls, struct GNUNET_SERVER_Client * client, const struct GNUNET_MessageHeader * message) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' message\n", "LOOKUP"); size_t msg_size = 0; size_t namelen; char name[MAX_DNS_NAME_LENGTH]; struct ClientLookupHandle *clh; char* nameptr = name; struct GNUNET_CRYPTO_RsaPrivateKey *key = NULL; struct GNUNET_CRYPTO_ShortHashCode zone; if (ntohs (message->size) < sizeof (struct GNUNET_GNS_ClientLookupMessage)) { GNUNET_break_op (0); GNUNET_SERVER_receive_done (client, GNUNET_OK); return; } GNUNET_SERVER_notification_context_add (nc, client); struct GNUNET_GNS_ClientLookupMessage *sh_msg = (struct GNUNET_GNS_ClientLookupMessage *) message; msg_size = ntohs(message->size); if (msg_size > GNUNET_SERVER_MAX_MESSAGE_SIZE) { GNUNET_break_op (0); GNUNET_SERVER_receive_done (client, GNUNET_OK); return; } GNUNET_STRINGS_utf8_tolower((char*)&sh_msg[1], &nameptr); namelen = strlen(name)+1; clh = GNUNET_malloc(sizeof(struct ClientLookupHandle)); clh->client = client; clh->name = GNUNET_malloc(namelen); strcpy(clh->name, name); clh->unique_id = sh_msg->id; clh->type = ntohl(sh_msg->type); clh->zone_key = NULL; if (strlen (name) > MAX_DNS_NAME_LENGTH) { GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "LOOKUP: %s is too long", name); clh->name = NULL; send_lookup_response(clh, 0, NULL); return; } if (1 == ntohl(sh_msg->use_default_zone)) zone = zone_hash; //Default zone else zone = sh_msg->zone; if (GNUNET_YES == auto_import_pkey) { if (1 == ntohl(sh_msg->use_default_zone)) key = zone_key; else { key = lookup_private_key(&zone); clh->zone_key = key; } gns_resolver_lookup_record(zone, zone, clh->type, name, key, default_lookup_timeout, &send_lookup_response, clh); } else { gns_resolver_lookup_record(zone, zone, clh->type, name, NULL, default_lookup_timeout, &send_lookup_response, clh); } }
/** * Handle a get authority message from the api * * @param cls the closure * @param client the client * @param message the message */ static void handle_get_authority(void *cls, struct GNUNET_SERVER_Client * client, const struct GNUNET_MessageHeader * message) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' message\n", "GET_AUTH"); size_t msg_size = 0; struct ClientGetAuthHandle *cah; char name[MAX_DNS_NAME_LENGTH]; char* nameptr = name; if (ntohs (message->size) < sizeof (struct GNUNET_GNS_ClientGetAuthMessage)) { GNUNET_break_op (0); GNUNET_SERVER_receive_done (client, GNUNET_OK); return; } GNUNET_SERVER_notification_context_add (nc, client); struct GNUNET_GNS_ClientGetAuthMessage *sh_msg = (struct GNUNET_GNS_ClientGetAuthMessage *) message; msg_size = ntohs(message->size); if (msg_size > GNUNET_SERVER_MAX_MESSAGE_SIZE) { GNUNET_break_op (0); GNUNET_SERVER_receive_done (client, GNUNET_OK); return; } GNUNET_STRINGS_utf8_tolower((char*)&sh_msg[1], &nameptr); cah = GNUNET_malloc(sizeof(struct ClientGetAuthHandle)); cah->client = client; cah->unique_id = sh_msg->id; if (strlen(name) < strlen(GNUNET_GNS_TLD)) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "GET_AUTH: %s is too short. Returning\n", name); cah->name = NULL; send_get_auth_response(cah, name); return; } if (strlen (name) > MAX_DNS_NAME_LENGTH) { GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "GET_AUTH: %s is too long", name); cah->name = NULL; send_get_auth_response(cah, name); return; } if (strcmp(name+strlen(name)-strlen(GNUNET_GNS_TLD), GNUNET_GNS_TLD) != 0) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "GET_AUTH: %s is not our domain. Returning\n", name); cah->name = NULL; send_get_auth_response(cah, name); return; } if (strcmp(name, GNUNET_GNS_TLD) == 0) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "GET_AUTH: %s is us. Returning\n", name); cah->name = NULL; send_get_auth_response(cah, name); return; } cah->name = GNUNET_malloc(strlen(name) - strlen(GNUNET_GNS_TLD) + 1); memset(cah->name, 0, strlen(name)-strlen(GNUNET_GNS_TLD) + 1); memcpy(cah->name, name, strlen(name)-strlen(GNUNET_GNS_TLD)); /* Start delegation resolution in our namestore */ gns_resolver_get_authority(zone_hash, zone_hash, name, &send_get_auth_response, cah); }
/** * Handle a shorten message from the api * * @param cls the closure * @param client the client * @param message the message */ static void handle_shorten(void *cls, struct GNUNET_SERVER_Client * client, const struct GNUNET_MessageHeader * message) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' message\n", "SHORTEN"); size_t msg_size = 0; struct ClientShortenHandle *csh; char name[MAX_DNS_NAME_LENGTH]; char* nameptr = name; struct GNUNET_CRYPTO_ShortHashCode zone; struct GNUNET_CRYPTO_RsaPrivateKey *key; if (ntohs (message->size) < sizeof (struct GNUNET_GNS_ClientShortenMessage)) { GNUNET_break_op (0); GNUNET_SERVER_receive_done (client, GNUNET_OK); return; } struct GNUNET_GNS_ClientShortenMessage *sh_msg = (struct GNUNET_GNS_ClientShortenMessage *) message; msg_size = ntohs(message->size); if (msg_size > GNUNET_SERVER_MAX_MESSAGE_SIZE) { GNUNET_break_op (0); GNUNET_SERVER_receive_done (client, GNUNET_OK); return; } csh = GNUNET_malloc(sizeof(struct ClientShortenHandle)); csh->client = client; csh->unique_id = sh_msg->id; csh->zone_key = NULL; GNUNET_STRINGS_utf8_tolower((char*)&sh_msg[1], &nameptr); if (strlen (name) < strlen(GNUNET_GNS_TLD)) { GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "SHORTEN: %s is too short", name); csh->name = NULL; send_shorten_response(csh, name); return; } if (strlen (name) > MAX_DNS_NAME_LENGTH) { GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "SHORTEN: %s is too long", name); csh->name = NULL; send_shorten_response(csh, name); return; } if (!is_gnunet_tld(name) && !is_zkey_tld(name)) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "%s is not our domain. Returning\n", name); csh->name = NULL; send_shorten_response(csh, name); return; } GNUNET_SERVER_notification_context_add (nc, client); if (1 == ntohl(sh_msg->use_default_zone)) zone = zone_hash; //Default zone else zone = sh_msg->zone; /* Start shortening */ if (GNUNET_YES == auto_import_pkey) { if (1 == ntohl(sh_msg->use_default_zone)) key = zone_key; else { key = lookup_private_key(&sh_msg->zone); csh->zone_key = key; } gns_resolver_shorten_name(zone, zone, name, key, &send_shorten_response, csh); } else gns_resolver_shorten_name(zone, zone, name, NULL, &send_shorten_response, csh); }
/** * Handle #GNUNET_MESSAGE_TYPE_CORE_INIT request. * * @param cls unused * @param client new client that sent #GNUNET_MESSAGE_TYPE_CORE_INIT * @param message the `struct InitMessage` (presumably) */ static void handle_client_init (void *cls, struct GNUNET_SERVER_Client *client, const struct GNUNET_MessageHeader *message) { const struct InitMessage *im; struct InitReplyMessage irm; struct GSC_Client *c; uint16_t msize; const uint16_t *types; uint16_t *wtypes; unsigned int i; /* check that we don't have an entry already */ c = find_client (client); if (NULL != c) { GNUNET_break (0); GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); return; } msize = ntohs (message->size); if (msize < sizeof (struct InitMessage)) { GNUNET_break (0); GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); return; } GNUNET_SERVER_notification_context_add (notifier, client); im = (const struct InitMessage *) message; types = (const uint16_t *) &im[1]; msize -= sizeof (struct InitMessage); c = GNUNET_malloc (sizeof (struct GSC_Client) + msize); c->client_handle = client; c->tcnt = msize / sizeof (uint16_t); c->options = ntohl (im->options); all_client_options |= c->options; c->types = (const uint16_t *) &c[1]; c->connectmap = GNUNET_CONTAINER_multipeermap_create (16, GNUNET_NO); GNUNET_assert (GNUNET_YES == GNUNET_CONTAINER_multipeermap_put (c->connectmap, &GSC_my_identity, NULL, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); wtypes = (uint16_t *) & c[1]; for (i = 0; i < c->tcnt; i++) wtypes[i] = ntohs (types[i]); GSC_TYPEMAP_add (wtypes, c->tcnt); GNUNET_CONTAINER_DLL_insert (client_head, client_tail, c); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client connecting to core service is interested in %u message types\n", (unsigned int) c->tcnt); /* send init reply message */ irm.header.size = htons (sizeof (struct InitReplyMessage)); irm.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_INIT_REPLY); irm.reserved = htonl (0); irm.my_identity = GSC_my_identity; send_to_client (c, &irm.header, GNUNET_NO); GSC_SESSIONS_notify_client_about_sessions (c); GNUNET_SERVER_receive_done (client, GNUNET_OK); }