/** * Change length of view * * If size is decreased, peers with higher indices are removed. * * @param len the (maximum) length for the view */ void View_change_len (uint32_t len) { uint32_t i; uint32_t *index; if (GNUNET_CONTAINER_multipeermap_size (mpm) < len) { /* Simply shrink */ /* We might simply clear and free the left over space */ GNUNET_array_grow (array, length, len); } else /* We have to remove elements */ { /* TODO find a way to preserve indices */ for (i = 0; i < len; i++) { index = GNUNET_CONTAINER_multipeermap_get (mpm, &array[i]); GNUNET_assert (NULL != index); GNUNET_free (index); } GNUNET_array_grow (array, length, len); GNUNET_CONTAINER_multipeermap_destroy (mpm); mpm = GNUNET_CONTAINER_multipeermap_create (len, GNUNET_NO); for (i = 0; i < len; i++) { index = GNUNET_new (uint32_t); *index = i; GNUNET_CONTAINER_multipeermap_put (mpm, &array[i], index, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); } } GNUNET_assert (length == len); }
/** * Function called to convert input argument into SQL parameters. * * @param cls closure * @param data pointer to input argument * @param data_len number of bytes in @a data (if applicable) * @param[out] param_values SQL data to set * @param[out] param_lengths SQL length data to set * @param[out] param_formats SQL format data to set * @param param_length number of entries available in the @a param_values, @a param_lengths and @a param_formats arrays * @param[out] scratch buffer for dynamic allocations (to be done via #GNUNET_malloc() * @param scratch_length number of entries left in @a scratch * @return -1 on error, number of offsets used in @a scratch otherwise */ static int qconv_uint16 (void *cls, const void *data, size_t data_len, void *param_values[], int param_lengths[], int param_formats[], unsigned int param_length, void *scratch[], unsigned int scratch_length) { const uint16_t *u_hbo = data; uint16_t *u_nbo; GNUNET_break (NULL == cls); if (1 != param_length) return -1; u_nbo = GNUNET_new (uint16_t); scratch[0] = u_nbo; *u_nbo = htons (*u_hbo); param_values[0] = (void *) u_nbo; param_lengths[0] = sizeof (uint16_t); param_formats[0] = 1; return 1; }
/** * @brief Create a new #PeerContext and insert it into the peer map * * @param peer the peer to create the #PeerContext for * * @return the #PeerContext */ static struct PeerContext * create_peer_ctx (const struct GNUNET_PeerIdentity *peer) { struct PeerContext *ctx; int ret; GNUNET_assert (GNUNET_NO == Peers_check_peer_known (peer)); ctx = GNUNET_new (struct PeerContext); ctx->peer_id = *peer; ctx->send_channel_flags = GNUNET_new (uint32_t); ctx->recv_channel_flags = GNUNET_new (uint32_t); ret = GNUNET_CONTAINER_multipeermap_put (peer_map, peer, ctx, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); GNUNET_assert (GNUNET_OK == ret); return ctx; }
/** * Establish a connection to a remote node. * @param hello the hello-Message for the target node * @param tsessionPtr the session handle that is to be set * @param may_reuse can we re-use an existing connection? * @return GNUNET_OK on success, GNUNET_SYSERR if the operation failed */ static int api_connect (const GNUNET_MessageHello * hello, GNUNET_TSession ** tsessionPtr, int may_reuse) { GNUNET_TSession *tsession; tsession = GNUNET_new (GNUNET_TSession); tsession->internal = GNUNET_malloc (GNUNET_sizeof_hello (hello)); tsession->peer = hello->senderIdentity; GNUNET_memcpy (tsession->internal, hello, GNUNET_sizeof_hello (hello)); tsession->ttype = smtpAPI.protocol_number; (*tsessionPtr) = tsession; return GNUNET_OK; }
/** * Insert peer into the view * * @param peer the peer to insert * * @return GNUNET_OK if peer was actually inserted * GNUNET_NO if peer was not inserted */ int View_put (const struct GNUNET_PeerIdentity *peer) { uint32_t *index; if ((length <= View_size ()) || /* If array is 'full' */ (GNUNET_YES == View_contains_peer (peer))) { return GNUNET_NO; } else { index = GNUNET_new (uint32_t); *index = (uint32_t) View_size (); array[*index] = *peer; GNUNET_CONTAINER_multipeermap_put (mpm, peer, index, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); return GNUNET_OK; } }
/** * Listen to the pipe, decode messages and send to core. */ static void * listenAndDistribute (void *unused) { char *line; unsigned int linesize; SMTPMessage *mp; FILE *fdes; char *retl; char *out; unsigned int size; GNUNET_TransportPacket *coreMP; int fd; unsigned int pos; linesize = ((GNUNET_MAX_BUFFER_SIZE * 4 / 3) + 8) * (MAX_CHAR_PER_LINE + 2) / MAX_CHAR_PER_LINE; /* maximum size of a line supported */ line = GNUNET_malloc (linesize + 2); /* 2 bytes for off-by-one errors, just to be safe... */ #define READLINE(l,limit) \ do { retl = fgets(l, (limit), fdes); \ if ( (retl == NULL) || (smtp_shutdown == GNUNET_YES)) {\ goto END; \ }\ if (core_api->load_monitor != NULL) \ GNUNET_network_monitor_notify_transmission(core_api->load_monitor, GNUNET_ND_DOWNLOAD, strlen(retl)); \ } while (0) while (smtp_shutdown == GNUNET_NO) { fd = OPEN (pipename, O_RDONLY | O_ASYNC); if (fd == -1) { if (smtp_shutdown == GNUNET_NO) GNUNET_thread_sleep (5 * GNUNET_CRON_SECONDS); continue; } fdes = fdopen (fd, "r"); while (smtp_shutdown == GNUNET_NO) { /* skip until end of header */ do { READLINE (line, linesize); } while ((line[0] != '\r') && (line[0] != '\n')); /* expect newline */ READLINE (line, linesize); /* read base64 encoded message; decode, process */ pos = 0; while (1) { pos = strlen (line) - 1; /* ignore new line */ READLINE (&line[pos], linesize - pos); /* read base64 encoded message; decode, process */ if ((line[pos] == '\r') || (line[pos] == '\n')) break; /* empty line => end of message! */ } size = GNUNET_STRINGS_base64_decode (line, pos, &out); if (size < sizeof (SMTPMessage)) { GNUNET_GE_BREAK (ectx, 0); GNUNET_free (out); goto END; } mp = (SMTPMessage *) &out[size - sizeof (SMTPMessage)]; if (ntohs (mp->header.size) != size) { GNUNET_GE_LOG (ectx, GNUNET_GE_WARNING | GNUNET_GE_BULK | GNUNET_GE_USER, _("Received malformed message via %s. Ignored.\n"), "SMTP"); #if DEBUG_SMTP GNUNET_GE_LOG (ectx, GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER, "Size returned by base64=%d, in the msg=%d.\n", size, ntohl (mp->size)); #endif GNUNET_free (out); goto END; } if (stats != NULL) stats->change (stat_bytesReceived, size); coreMP = GNUNET_new (GNUNET_TransportPacket); coreMP->msg = out; coreMP->size = size - sizeof (SMTPMessage); coreMP->tsession = NULL; coreMP->sender = mp->sender; #if DEBUG_SMTP GNUNET_GE_LOG (ectx, GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER, "SMTP message passed to the core.\n"); #endif core_api->receive (coreMP); } END: #if DEBUG_SMTP GNUNET_GE_LOG (ectx, GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER, "SMTP message processed.\n"); #endif if (fdes != NULL) fclose (fdes); } GNUNET_free (line); return NULL; }