📄 messaging.c
字号:
&received_msg->sender, sizeof (GNUNET_HashCode)))) pos = pos->next; GNUNET_GE_ASSERT (NULL, pos != NULL); room->message_callback (room->message_callback_cls, room, &received_msg->sender, pos->meta, message_content, ntohl (received_msg->msg_options)); GNUNET_free (message_content); break; case GNUNET_CS_PROTO_CHAT_CONFIRMATION_RECEIPT: if (size < sizeof (CS_chat_MESSAGE_ConfirmationReceipt)) { malformed = GNUNET_YES; continue; } receipt = (CS_chat_MESSAGE_ConfirmationReceipt *) reply; if (room->confirmation_callback != NULL) room->confirmation_callback (room->confirmation_cls, room, ntohl (receipt->sequence_number), GNUNET_ntohll (receipt->timestamp), &receipt->target, &receipt->content, &receipt->signature); break; default: GNUNET_GE_BREAK (NULL, 0); break; } } GNUNET_free_non_null (reply); while (members != NULL) { pos = members; members = pos->next; GNUNET_meta_data_destroy (pos->meta); GNUNET_free (pos); } return NULL;}/** * Returns the private key on success, * NULL on error. */static GNUNET_RSA_PrivateKeyEncoded *GNUNET_CHAT_initPrivateKey (struct GNUNET_GE_Context *ectx, struct GNUNET_GC_Configuration *cfg, const char *nick_name){ char *gnHome; char *keyfile; GNUNET_RSA_PrivateKeyEncoded *encPrivateKey; struct GNUNET_RSA_PrivateKey *privKey; unsigned short len; int res; if (-1 == GNUNET_GC_get_configuration_value_filename (cfg, "PATHS", "GNUNET_HOME", GNUNET_DEFAULT_HOME_DIRECTORY, &gnHome)) return NULL; GNUNET_disk_directory_create (ectx, gnHome); if (GNUNET_YES != GNUNET_disk_directory_test (ectx, gnHome)) { GNUNET_GE_LOG (ectx, GNUNET_GE_FATAL | GNUNET_GE_ADMIN | GNUNET_GE_USER | GNUNET_GE_IMMEDIATE, _("Failed to access GNUnet home directory `%s'\n"), gnHome); GNUNET_free (gnHome); return NULL; } /* read or create public key */ keyfile = GNUNET_malloc (strlen (gnHome) + strlen (NICK_IDENTITY_PREFIX) + strlen (nick_name) + 2); strcpy (keyfile, gnHome); GNUNET_free (gnHome); if (keyfile[strlen (keyfile) - 1] != DIR_SEPARATOR) strcat (keyfile, DIR_SEPARATOR_STR); strcat (keyfile, NICK_IDENTITY_PREFIX); strcat (keyfile, nick_name); res = 0; if (GNUNET_YES == GNUNET_disk_file_test (ectx, keyfile)) { res = GNUNET_disk_file_read (ectx, keyfile, sizeof (unsigned short), &len); } encPrivateKey = NULL; if (res == sizeof (unsigned short)) { encPrivateKey = (GNUNET_RSA_PrivateKeyEncoded *) GNUNET_malloc (ntohs (len)); if (ntohs (len) != GNUNET_disk_file_read (ectx, keyfile, ntohs (len), encPrivateKey)) { GNUNET_free (encPrivateKey); GNUNET_GE_LOG (ectx, GNUNET_GE_WARNING | GNUNET_GE_USER | GNUNET_GE_IMMEDIATE | GNUNET_GE_ADMIN, _ ("Existing key in file `%s' failed format check, creating new key.\n"), keyfile); encPrivateKey = NULL; } } if (encPrivateKey == NULL) { /* make new hostkey */ GNUNET_GE_LOG (ectx, GNUNET_GE_INFO | GNUNET_GE_USER | GNUNET_GE_BULK, _ ("Creating new key for this nickname (this may take a while).\n")); privKey = GNUNET_RSA_create_key (); GNUNET_GE_ASSERT (ectx, privKey != NULL); encPrivateKey = GNUNET_RSA_encode_key (privKey); GNUNET_GE_ASSERT (ectx, encPrivateKey != NULL); GNUNET_disk_file_write (ectx, keyfile, encPrivateKey, ntohs (encPrivateKey->len), "600"); GNUNET_RSA_free_key (privKey); GNUNET_GE_LOG (ectx, GNUNET_GE_INFO | GNUNET_GE_USER | GNUNET_GE_BULK, _("Done creating key.\n")); } GNUNET_free (keyfile); GNUNET_GE_ASSERT (ectx, encPrivateKey != NULL); return encPrivateKey;}/** * Join a chat room. * * @param nick_name nickname of the user joining (used to * determine which public key to use); * the nickname should probably also * be used in the member_info (as "EXTRACTOR_TITLE") * @param member_info information about the joining member * @param memberInfo public information about you * @param messageCallback which function to call if a message has * been received? * @param message_cls argument to callback * @param memberCallback which function to call for join/leave notifications * @param confirmationCallback which function to call for confirmations (maybe NULL) * @return NULL on error */struct GNUNET_CHAT_Room *GNUNET_CHAT_join_room (struct GNUNET_GE_Context *ectx, struct GNUNET_GC_Configuration *cfg, const char *nick_name, struct GNUNET_MetaData *member_info, const char *room_name, GNUNET_CHAT_MSG_OPTIONS msg_options, GNUNET_CHAT_MessageCallback messageCallback, void *message_cls, GNUNET_CHAT_MemberListCallback memberCallback, void *member_cls, GNUNET_CHAT_MessageConfirmation confirmationCallback, void *confirmation_cls, GNUNET_HashCode * me){ struct GNUNET_CHAT_Room *chat_room; struct GNUNET_ClientServerConnection *sock; GNUNET_RSA_PrivateKeyEncoded *key; struct GNUNET_RSA_PrivateKey *priv_key; GNUNET_RSA_PublicKey pub_key; key = GNUNET_CHAT_initPrivateKey (ectx, cfg, nick_name); if (key == NULL) return NULL; priv_key = GNUNET_RSA_decode_key (key); GNUNET_RSA_get_public_key (priv_key, &pub_key); GNUNET_hash (&pub_key, sizeof (GNUNET_RSA_PublicKey), me); GNUNET_pseudonym_add (ectx, cfg, me, member_info); GNUNET_RSA_free_key (priv_key); sock = GNUNET_client_connection_create (ectx, cfg); if (sock == NULL) { GNUNET_free (key); return NULL; } chat_room = GNUNET_malloc (sizeof (struct GNUNET_CHAT_Room)); chat_room->msg_options = msg_options; chat_room->room_name = GNUNET_strdup (room_name); chat_room->member_info = GNUNET_meta_data_duplicate (member_info); chat_room->my_private_key = key; chat_room->message_callback = messageCallback; chat_room->message_callback_cls = message_cls; chat_room->member_list_callback = memberCallback; chat_room->member_list_callback_cls = member_cls; chat_room->confirmation_callback = confirmationCallback; chat_room->confirmation_cls = confirmation_cls; chat_room->ectx = ectx; chat_room->cfg = cfg; chat_room->sock = sock; chat_room->listen_thread = GNUNET_thread_create (&poll_thread, chat_room, 1024 * 2); if (chat_room->listen_thread == NULL) { GNUNET_free (chat_room->room_name); GNUNET_client_connection_destroy (chat_room->sock); GNUNET_meta_data_destroy (chat_room->member_info); GNUNET_free (chat_room); GNUNET_free (key); return NULL; } if (GNUNET_SYSERR == GNUNET_CHAT_rejoin_room (chat_room)) { GNUNET_CHAT_leave_room (chat_room); return NULL; } return chat_room;}/** * Leave a chat room. */voidGNUNET_CHAT_leave_room (struct GNUNET_CHAT_Room *chat_room){ void *unused; chat_room->shutdown_flag = GNUNET_YES; GNUNET_client_connection_close_forever (chat_room->sock); GNUNET_thread_stop_sleep (chat_room->listen_thread); GNUNET_thread_join (chat_room->listen_thread, &unused); GNUNET_free (chat_room->room_name); GNUNET_meta_data_destroy (chat_room->member_info); GNUNET_client_connection_destroy (chat_room->sock); GNUNET_free (chat_room->my_private_key); GNUNET_free (chat_room);}/** * Send a message. * * @param receiver use NULL to send to everyone in the room * @return GNUNET_OK on success, GNUNET_SYSERR on error */intGNUNET_CHAT_send_message (struct GNUNET_CHAT_Room *room, const char *message, GNUNET_CHAT_MSG_OPTIONS options, const GNUNET_RSA_PublicKey * receiver, unsigned int *sequence_number){ int ret = GNUNET_OK; CS_chat_MESSAGE_TransmitRequest *msg_to_send; unsigned int msg_size; msg_size = strlen (message) + sizeof (CS_chat_MESSAGE_TransmitRequest); if (msg_size > GNUNET_MAX_BUFFER_SIZE - 8) return GNUNET_SYSERR; msg_to_send = GNUNET_malloc (msg_size); msg_to_send->header.size = htons (msg_size); msg_to_send->header.type = htons (GNUNET_CS_PROTO_CHAT_TRANSMIT_REQUEST); msg_to_send->msg_options = htonl (options); *sequence_number = room->sequence_number++; msg_to_send->sequence_number = htonl (*sequence_number); msg_to_send->reserved = htonl (0); if (receiver == NULL) memset (&msg_to_send->target, 0, sizeof (GNUNET_HashCode)); else GNUNET_hash (receiver, sizeof (GNUNET_RSA_PublicKey), &msg_to_send->target); memcpy (&msg_to_send[1], message, strlen (message)); ret = GNUNET_client_connection_write (room->sock, &msg_to_send->header); GNUNET_free (msg_to_send); return ret;}/* end of messaging.c */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -