rstatus_t dmsg_write(struct mbuf *mbuf, uint64_t msg_id, uint8_t type, struct conn *conn, uint32_t payload_len) { mbuf_write_string(mbuf, &MAGIC_STR); mbuf_write_uint64(mbuf, msg_id); mbuf_write_char(mbuf, ' '); mbuf_write_uint8(mbuf, type); mbuf_write_char(mbuf, ' '); //encryption bit if (conn->dnode_secured) { mbuf_write_uint8(mbuf, 1); } else { mbuf_write_uint8(mbuf, 0); } mbuf_write_char(mbuf, ' '); mbuf_write_uint8(mbuf, version); //mbuf_write_string(mbuf, &CRLF_STR); mbuf_write_char(mbuf, ' '); mbuf_write_char(mbuf, '*'); //write aes key unsigned char *aes_key = conn->aes_key; if (conn->dnode_secured && conn->dnode_crypto_state == 0) { mbuf_write_uint32(mbuf, AES_ENCRYPTED_KEYLEN); } else { mbuf_write_uint32(mbuf, 1); } mbuf_write_char(mbuf, ' '); //mbuf_write_string(mbuf, data); if (conn->dnode_secured && conn->dnode_crypto_state == 0) { #ifdef DN_DEBUG_LOG loga("AES key to be encrypted : %s \n", base64_encode(aes_key, 32)); #endif dyn_rsa_encrypt(aes_key, aes_encrypted_buf); mbuf_write_bytes(mbuf, aes_encrypted_buf, AES_ENCRYPTED_KEYLEN); conn->dnode_crypto_state = 1; } else { mbuf_write_char(mbuf, 'd'); //TODOs: replace with another string } //mbuf_write_string(mbuf, &CRLF_STR); mbuf_write_char(mbuf, ' '); mbuf_write_char(mbuf, '*'); mbuf_write_uint32(mbuf, payload_len); mbuf_write_string(mbuf, &CRLF_STR); #ifdef DN_DEBUG_LOG log_hexdump(LOG_VERB, mbuf->pos, mbuf_length(mbuf), "dyn message producer: "); #endif return DN_OK; }
//Used in gossip forwarding msg only for now rstatus_t dmsg_write_mbuf(struct mbuf *mbuf, uint64_t msg_id, uint8_t type, struct conn *conn, uint32_t plen) { mbuf_write_string(mbuf, &MAGIC_STR); mbuf_write_uint64(mbuf, msg_id); mbuf_write_char(mbuf, ' '); mbuf_write_uint8(mbuf, type); mbuf_write_char(mbuf, ' '); //encryption bit if (conn->dnode_secured) { mbuf_write_uint8(mbuf, 1); } else { mbuf_write_uint8(mbuf, 0); } mbuf_write_char(mbuf, ' '); mbuf_write_uint8(mbuf, version); //same-dc mbuf_write_char(mbuf, ' '); if (conn->same_dc) mbuf_write_uint8(mbuf, 1); else mbuf_write_uint8(mbuf, 0); //mbuf_write_string(mbuf, &CRLF_STR); mbuf_write_char(mbuf, ' '); mbuf_write_char(mbuf, '*'); //write aes key unsigned char *aes_key = conn->aes_key; if (conn->dnode_secured) { mbuf_write_uint32(mbuf, dyn_rsa_size()); } else { mbuf_write_uint32(mbuf, 1); } mbuf_write_char(mbuf, ' '); //mbuf_write_mbuf(mbuf, data); if (conn->dnode_secured) { dyn_rsa_encrypt(aes_key, aes_encrypted_buf); mbuf_write_bytes(mbuf, aes_encrypted_buf, dyn_rsa_size()); } else { mbuf_write_char(mbuf, 'a'); //TODOs: replace with another string } //mbuf_write_string(mbuf, &CRLF_STR); mbuf_write_char(mbuf, ' '); mbuf_write_char(mbuf, '*'); mbuf_write_uint32(mbuf, plen); mbuf_write_string(mbuf, &CRLF_STR); return DN_OK; }
void mbuf_write_uint64(struct mbuf *mbuf, uint64_t num) { if (num < 10) { mbuf_write_char(mbuf, '0' + num); return; } mbuf_write_uint64(mbuf, num / 10); mbuf_write_char(mbuf, '0' + (num % 10)); }
rstatus_t dnode_peer_handshake_announcing(void *rmsg) { rstatus_t status; struct ring_msg *msg = rmsg; struct server_pool *sp = msg->sp; log_debug(LOG_VVERB, "dyn: handshaking peers"); struct array *peers = &sp->peers; uint32_t i,nelem; nelem = array_n(peers); //we assume one mbuf is enough for now - will enhance with multiple mbufs later struct mbuf *mbuf = mbuf_get(); if (mbuf == NULL) { log_debug(LOG_VVERB, "Too bad, not enough memory!"); return DN_ENOMEM; } //annoucing myself by sending msg: 'dc$rack$token,started_ts,node_state,node_dns' mbuf_write_string(mbuf, &sp->dc); mbuf_write_char(mbuf, '$'); mbuf_write_string(mbuf, &sp->rack); mbuf_write_char(mbuf, '$'); struct dyn_token *token = (struct dyn_token *) array_get(&sp->tokens, 0); if (token == NULL) { log_debug(LOG_VVERB, "Why? This should not be null!"); mbuf_put(mbuf); return DN_ERROR; } mbuf_write_uint32(mbuf, token->mag[0]); mbuf_write_char(mbuf, ','); int64_t cur_ts = (int64_t)time(NULL); mbuf_write_uint64(mbuf, cur_ts); mbuf_write_char(mbuf, ','); mbuf_write_uint8(mbuf, sp->ctx->dyn_state); mbuf_write_char(mbuf, ','); char *broadcast_addr = get_broadcast_address(sp); mbuf_write_bytes(mbuf, broadcast_addr, dn_strlen(broadcast_addr)); //for each peer, send a registered msg for (i = 0; i < nelem; i++) { struct server *peer = (struct server *) array_get(peers, i); if (peer->is_local) continue; log_debug(LOG_VVERB, "Gossiping to node '%.*s'", peer->name.len, peer->name.data); struct conn * conn = dnode_peer_conn(peer); if (conn == NULL) { //running out of connection due to memory exhaust log_debug(LOG_DEBUG, "Unable to obtain a connection object"); return DN_ERROR; } status = dnode_peer_connect(sp->ctx, peer, conn); if (status != DN_OK ) { dnode_peer_close(sp->ctx, conn); log_debug(LOG_DEBUG, "Error happened in connecting on conn %d", conn->sd); return DN_ERROR; } //conn-> dnode_peer_gossip_forward(sp->ctx, conn, sp->redis, mbuf); //peer_gossip_forward1(sp->ctx, conn, sp->redis, &data); } //free this as nobody else will do //mbuf_put(mbuf); return DN_OK; }