Ejemplo n.º 1
0
static rstatus_t
memcache_append_key(struct msg *r, uint8_t *key, uint32_t keylen)
{
    struct mbuf *mbuf;
    struct keypos *kpos;

    mbuf = msg_ensure_mbuf(r, keylen + 2);
    if (mbuf == NULL) {
        return NC_ENOMEM;
    }

    kpos = array_push(r->keys);
    if (kpos == NULL) {
        return NC_ENOMEM;
    }

    kpos->start = mbuf->last;
    kpos->end = mbuf->last + keylen;
    mbuf_copy(mbuf, key, keylen);
    r->mlen += keylen;

    mbuf_copy(mbuf, (uint8_t *)" ", 1);
    r->mlen += 1;
    return NC_OK;
}
Ejemplo n.º 2
0
rstatus_t dyn_aes_decrypt(unsigned char *enc_msg, size_t enc_msg_len, struct mbuf *mbuf, unsigned char *aes_key) {
	if (ENCRYPTION) {
		size_t dec_len   = 0;
		size_t block_len = 0;

		ASSERT(mbuf != NULL && mbuf->last == mbuf->pos);

		//if(!EVP_DecryptInit_ex(aes_decrypt_ctx, aes_cipher, NULL, aes_key, aes_iv)) {
		if(!EVP_DecryptInit_ex(aes_decrypt_ctx, aes_cipher, NULL, aes_key, aes_key)) {
			return DN_ERROR;
		}

		if(!EVP_DecryptUpdate(aes_decrypt_ctx, mbuf->pos, (int*) &block_len, enc_msg, (int)enc_msg_len)) {
			return DN_ERROR;
		}
		dec_len += block_len;

		if(!EVP_DecryptFinal_ex(aes_decrypt_ctx, mbuf->pos + dec_len, (int*) &block_len)) {
			return DN_ERROR;
		}
		dec_len += block_len;
		mbuf->last = mbuf->pos + dec_len;

		EVP_CIPHER_CTX_cleanup(aes_decrypt_ctx);

		return (int) dec_len;
	}

	mbuf_copy(mbuf, enc_msg, enc_msg_len);
	return (int) enc_msg_len;

}
Ejemplo n.º 3
0
/*
 * Put partial data to the next mbuf.
 */
struct mbuf * mbuf_split(struct context *ctx, struct mbuf *mbuf, uint8_t *pos,
        mbuf_copy_t cb, void *cbarg)
{
    struct mbuf *nbuf;
    size_t size;

    nbuf = mbuf_get(ctx);
    if (nbuf == NULL) {
        return NULL;
    }

    if (cb != NULL) {
        /* precopy nbuf */
        cb(nbuf, cbarg);
    }

    /* copy data from mbuf to nbuf */
    size = (size_t)(mbuf->last - pos);
    mbuf_copy(nbuf, pos, size);

    /* adjust mbuf */
    mbuf->last = pos;

    return nbuf;
}
Ejemplo n.º 4
0
/*
 * Split mbuf h into h and t by copying data from h to t. Before
 * the copy, we invoke a precopy handler cb that will copy a predefined
 * string to the head of t.
 *
 * Return new mbuf t, if the split was successful.
 */
struct mbuf *
mbuf_split(struct mhdr *h, uint8_t *pos, mbuf_copy_t cb, void *cbarg)
{
    struct mbuf *mbuf, *nbuf;
    size_t size;

    ASSERT(!STAILQ_EMPTY(h));

    mbuf = STAILQ_LAST(h, mbuf, next);
    ASSERT(pos >= mbuf->pos && pos <= mbuf->last);

    nbuf = mbuf_get();
    if (nbuf == NULL) {
        return NULL;
    }

    if (cb != NULL) {
        /* precopy nbuf */
        cb(nbuf, cbarg);
    }

	/* copy data from mbuf to nbuf */
    size = (size_t)(mbuf->last - pos);
    mbuf_copy(nbuf, pos, size);

    /* adjust mbuf */
    mbuf->last = pos;

    log_debug(LOG_VVERB, "split into mbuf %p len %"PRIu32" and nbuf %p len "
              "%"PRIu32" copied %zu bytes", mbuf, mbuf_length(mbuf), nbuf,
              mbuf_length(nbuf), size);

    return nbuf;
}
Ejemplo n.º 5
0
/*
 * fill the mbuf in the msg with the content
 */
int msg_append_full(struct msg *msg, const uint8_t *pos, uint32_t n)
{
    struct mbuf *mbuf;
    uint32_t left, len;
    mbuf_base *mb = msg->mb;
    const uint8_t *start;

    start = pos;
    left = n;

    while (left > 0) {
        mbuf = listLastValue(msg->data);
        if (mbuf == NULL || mbuf_size(mbuf) == 0) {
            mbuf = mbuf_get(mb);
            if (mbuf == NULL) {
                log_error("ERROR: Mbuf get failed: out of memory");
                return RMT_ENOMEM;
            }
            listAddNodeTail(msg->data, mbuf);
        }

        len = MIN(left, mbuf_size(mbuf));
        mbuf_copy(mbuf, start, len);
        left -= len;
        start += len;
        msg->mlen += len;
    }
    
    return RMT_OK;
}
Ejemplo n.º 6
0
rstatus_t dyn_aes_encrypt(const unsigned char *msg, size_t msg_len, struct mbuf *mbuf, unsigned char *aes_key) {
	if (ENCRYPTION) {
		size_t block_len  = 0;
		size_t enc_msg_len = 0;

		ASSERT(mbuf != NULL && mbuf->last == mbuf->pos);

		//if(!EVP_EncryptInit_ex(aes_encrypt_ctx, aes_cipher, NULL, aes_key, aes_iv)) {
		if(!EVP_EncryptInit_ex(aes_encrypt_ctx, aes_cipher, NULL, aes_key, aes_key)) {
			return DN_ERROR;
		}

		if(!EVP_EncryptUpdate(aes_encrypt_ctx, mbuf->start, (int*)&block_len, (unsigned char*) msg, msg_len)) {
			return DN_ERROR;
		}
		enc_msg_len += block_len;

		if(!EVP_EncryptFinal_ex(aes_encrypt_ctx, mbuf->start + enc_msg_len, (int*) &block_len)) {
			return DN_ERROR;
		}

		EVP_CIPHER_CTX_cleanup(aes_encrypt_ctx);
		mbuf->last = mbuf->pos + enc_msg_len + block_len;

		return enc_msg_len + block_len;
	} else {
		mbuf_copy(mbuf, msg, msg_len);
		return (int) msg_len;
	}
}
Ejemplo n.º 7
0
void dyn_parse_rsp(struct msg *r)
{
	if (log_loggable(LOG_VVERB)) {
		log_debug(LOG_VVERB, ":::::::::::::::::::::: In dyn_parse_rsp, start to process response :::::::::::::::::::::::: ");
		msg_dump(r);
	}

	if (dyn_parse_core(r)) {
		struct dmsg *dmsg = r->dmsg;
		struct mbuf *b = STAILQ_LAST(&r->mhdr, mbuf, next);

		if (dmsg->type != DMSG_UNKNOWN && dmsg->type != DMSG_RES) {
			log_debug(LOG_DEBUG, "Resp parser: I got a dnode msg of type %d", dmsg->type);
			r->state = 0;
			r->result = MSG_PARSE_OK;
			r->dyn_state = DYN_DONE;
			return;
		}

		//check whether we need to decrypt the payload
		if (dmsg->bit_field == 1) {
			//dmsg->owner->owner->dnode_secured = 1;
			struct mbuf *decrypted_buf = mbuf_get();
			if (decrypted_buf == NULL) {
				log_debug(LOG_INFO, "Unable to obtain an mbuf for dnode msg's header!");
				r->result = MSG_OOM_ERROR;
				return;
			}

			//Dont need to decrypt AES key - pull it out from the conn
			dyn_aes_decrypt(dmsg->payload, dmsg->plen, decrypted_buf, r->owner->aes_key);

			b->pos = b->pos + dmsg->plen;
			r->pos = decrypted_buf->start;
			mbuf_copy(decrypted_buf, b->pos, mbuf_length(b));
			mbuf_insert(&r->mhdr, decrypted_buf);
			mbuf_remove(&r->mhdr, b);
			mbuf_put(b);
			r->mlen = mbuf_length(decrypted_buf);
		}

		if (r->redis) {
			return redis_parse_rsp(r);
		}

		return memcache_parse_rsp(r);
	}

	//bad case
	if (log_loggable(LOG_DEBUG)) {
		log_debug(LOG_DEBUG, "Resp: bad message - cannot parse");  //fix me to do something
		msg_dump(r);
	}

	r->result = MSG_PARSE_AGAIN;

}
Ejemplo n.º 8
0
rstatus_t
dnode_peer_forward_state(void *rmsg)
{
	rstatus_t status;
	struct ring_msg *msg = rmsg;
	struct server_pool *sp = msg->sp;
	log_debug(LOG_VVERB, "dnode_peer_forward_state: forwarding");

	//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;
	}

	mbuf_copy(mbuf, msg->data, msg->len);

	struct array *peers = &sp->peers;
	uint32_t i,nelem;
	nelem = array_n(peers);

	//pick a random peer
	int ran_index = rand() % nelem;

	if (ran_index == 0)
	   ran_index += 1;

	struct server *peer = (struct server *) array_get(peers, ran_index);

	//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_ERR, "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_ERR, "Error happened in connecting on conn %d", conn->sd);
		return DN_ERROR;
	}

	dnode_peer_gossip_forward(sp->ctx, conn, sp->redis, mbuf);

	//free this as nobody else will do
	//mbuf_put(mbuf);

	return status;
}
Ejemplo n.º 9
0
/*
 * Post-split copy handler invoked when the request is a multi vector -
 * 'get' or 'gets' request and has already been split into two requests
 */
rstatus_t
memcache_post_splitcopy(struct msg *r)
{
    struct mbuf *mbuf;
    struct string crlf = string(CRLF);

    ASSERT(r->request);
    ASSERT(!STAILQ_EMPTY(&r->mhdr));

    mbuf = STAILQ_LAST(&r->mhdr, mbuf, next);
    mbuf_copy(mbuf, crlf.data, crlf.len);

    return FC_OK;
}
Ejemplo n.º 10
0
/*
 * Pre-split copy handler invoked when the request is a multi vector -
 * 'get' or 'gets' request and is about to be split into two requests
 */
void
memcache_pre_splitcopy(struct mbuf *mbuf, void *arg)
{
    struct msg *r = arg;                  /* request vector */
    struct string get = string("get ");   /* 'get ' string */
    struct string gets = string("gets "); /* 'gets ' string */

    ASSERT(r->request);
    ASSERT(mbuf_empty(mbuf));

    switch (r->type) {
    case MSG_REQ_GET:
        mbuf_copy(mbuf, get.data, get.len);
        break;

    case MSG_REQ_GETS:
        mbuf_copy(mbuf, gets.data, gets.len);
        break;

    default:
        NOT_REACHED();
    }
}
Ejemplo n.º 11
0
/*
 * append small(small than a mbuf) content into msg
 */
int
msg_append(struct msg *msg, uint8_t *pos, size_t n)
{
    struct mbuf *mbuf;

    ASSERT(n <= mbuf_data_size(msg->mb));

    mbuf = msg_ensure_mbuf(msg, n);
    if (mbuf == NULL) {
        return RMT_ENOMEM;
    }

    ASSERT(n <= mbuf_size(mbuf));

    mbuf_copy(mbuf, pos, n);
    msg->mlen += (uint32_t)n;
    return RMT_OK;
}
Ejemplo n.º 12
0
/*
 * prepend small(small than a mbuf) content into msg
 */
int
msg_prepend(struct msg *msg, uint8_t *pos, size_t n)
{
    mbuf_base *mb = msg->mb;
    struct mbuf *mbuf;

    mbuf = mbuf_get(mb);
    if (mbuf == NULL) {
        return RMT_ENOMEM;
    }

    ASSERT(n <= mbuf_size(mbuf));

    mbuf_copy(mbuf, pos, n);
    msg->mlen += (uint32_t)n;

    listAddNodeHead(msg->data, mbuf);

    return RMT_OK;
}
Ejemplo n.º 13
0
/*
 * note: we should not call conn_add_out here.
 * because we may call append many times.
 */
rstatus_t
conn_sendq_append(struct conn *conn, char *pos, size_t n)
{
    struct mbuf *mbuf;
    size_t bytes = 0;
    size_t len;

    while (bytes < n) {
        mbuf = STAILQ_LAST(&conn->send_queue, mbuf, next);
        if ((mbuf == NULL) || mbuf_full(mbuf)) {
            mbuf = mbuf_get();
            if (mbuf == NULL) {
                return NC_ENOMEM;
            }
            mbuf_insert(&conn->send_queue, mbuf);
        }

        len = MIN(mbuf_size(mbuf), n - bytes);
        mbuf_copy(mbuf, (uint8_t *)pos + bytes, len);
        bytes += len;
    }

    return NC_OK;
}
Ejemplo n.º 14
0
void mbuf_write_bytes(struct mbuf *mbuf, char *data, int len)
{
    mbuf_copy(mbuf, data, len);
}
Ejemplo n.º 15
0
void mbuf_write_mbuf(struct mbuf *mbuf, struct mbuf *data)
{
    mbuf_copy(mbuf, data->pos, data->last - data->pos);
}
Ejemplo n.º 16
0
void 
mbuf_write_string(struct mbuf *mbuf, struct string *s)
{
   ASSERT(s->len < mbuf_size(mbuf));
   mbuf_copy(mbuf, s->data, s->len);
}
Ejemplo n.º 17
0
void dyn_parse_rsp(struct msg *r)
{
	if (log_loggable(LOG_VVERB)) {
		log_debug(LOG_VVERB, ":::::::::::::::::::::: In dyn_parse_rsp, start to process response :::::::::::::::::::::::: ");
		msg_dump(r);
	}

	bool done_parsing = false;
	struct mbuf *b = STAILQ_LAST(&r->mhdr, mbuf, next);
	if (dyn_parse_core(r)) {
		struct dmsg *dmsg = r->dmsg;
		struct conn *conn = r->owner;
		conn->same_dc = dmsg->same_dc;

		if (dmsg->type != DMSG_UNKNOWN && dmsg->type != DMSG_RES) {
			log_debug(LOG_DEBUG, "Resp parser: I got a dnode msg of type %d", dmsg->type);
			r->state = 0;
			r->result = MSG_PARSE_OK;
			r->dyn_state = DYN_DONE;
			return;
		}

		if (r->dyn_state == DYN_DONE && dmsg->bit_field == 1) {
			dmsg->owner->owner->dnode_secured = 1;
			r->owner->dnode_crypto_state = 1;
			r->dyn_state = DYN_POST_DONE;
			r->result = MSG_PARSE_REPAIR;

			if (dmsg->mlen > 1) {
				//Decrypt AES key
				dyn_rsa_decrypt(dmsg->data, aes_decrypted_buf);
				strncpy(r->owner->aes_key, aes_decrypted_buf, strlen(aes_decrypted_buf));
			}

			if (dmsg->plen + b->pos <= b->last) {
				struct mbuf *decrypted_buf = mbuf_get();
				if (decrypted_buf == NULL) {
					loga("Unable to obtain an mbuf for dnode msg's header!");
					r->result = MSG_OOM_ERROR;
					return;
				}

				dyn_aes_decrypt(b->pos, dmsg->plen, decrypted_buf, r->owner->aes_key);

				b->pos = b->pos + dmsg->plen;
				r->pos = decrypted_buf->start;
				mbuf_copy(decrypted_buf, b->pos, mbuf_length(b));

				mbuf_insert(&r->mhdr, decrypted_buf);
				mbuf_remove(&r->mhdr, b);
				mbuf_put(b);

				r->mlen = mbuf_length(decrypted_buf);

				return data_store_parse_rsp(r);
			}

			//Subtract already received bytes
			dmsg->plen -= b->last - b->pos;
			return;

		} else if (r->dyn_state == DYN_POST_DONE) {
			struct mbuf *last_buf = STAILQ_LAST(&r->mhdr, mbuf, next);
			if (last_buf->read_flip == 1) {
				data_store_parse_rsp(r);
			} else {
				r->result = MSG_PARSE_AGAIN;
			}
			return;
		}

		if (done_parsing)
			return;

		return data_store_parse_rsp(r);
	}

	//bad case
	if (log_loggable(LOG_DEBUG)) {
		log_debug(LOG_DEBUG, "Resp: bad message - cannot parse");  //fix me to do something
		msg_dump(r);
	}

	r->result = MSG_PARSE_AGAIN;

}
Ejemplo n.º 18
0
void
dyn_parse_req(struct msg *r)
{
	if (log_loggable(LOG_VVERB)) {
		log_debug(LOG_VVERB, ":::::::::::::::::::::: In dyn_parse_req, start to process request :::::::::::::::::::::: ");
		msg_dump(r);
	}

	bool done_parsing = false;
	struct mbuf *b = STAILQ_LAST(&r->mhdr, mbuf, next);

	if (dyn_parse_core(r)) {
		struct dmsg *dmsg = r->dmsg;
		struct conn *conn = r->owner;
		conn->same_dc = dmsg->same_dc;

		if (dmsg->type != DMSG_UNKNOWN && dmsg->type != DMSG_REQ &&
				dmsg->type != DMSG_REQ_FORWARD && dmsg->type != GOSSIP_SYN) {
			r->state = 0;
			r->result = MSG_PARSE_OK;
			r->dyn_state = DYN_DONE;
			return;
		}

		if (r->dyn_state == DYN_DONE && dmsg->bit_field == 1) {
			dmsg->owner->owner->dnode_secured = 1;
			r->owner->dnode_crypto_state = 1;
			r->dyn_state = DYN_POST_DONE;
			r->result = MSG_PARSE_REPAIR;

			if (dmsg->mlen > 1) {
				//Decrypt AES key
				dyn_rsa_decrypt(dmsg->data, aes_decrypted_buf);
				strncpy(r->owner->aes_key, aes_decrypted_buf, strlen(aes_decrypted_buf));
			}

			if (dmsg->plen + b->pos <= b->last) {
				struct mbuf *decrypted_buf = mbuf_get();
				if (decrypted_buf == NULL) {
					loga("Unable to obtain an mbuf for dnode msg's header!");
					r->result = MSG_OOM_ERROR;
					return;
				}

				dyn_aes_decrypt(b->pos, dmsg->plen, decrypted_buf, r->owner->aes_key);

				b->pos = b->pos + dmsg->plen;
				r->pos = decrypted_buf->start;
				mbuf_copy(decrypted_buf, b->pos, mbuf_length(b));

				mbuf_insert(&r->mhdr, decrypted_buf);
				mbuf_remove(&r->mhdr, b);
				mbuf_put(b);

				r->mlen = mbuf_length(decrypted_buf);

				data_store_parse_req(r);

			}

			//substract alraedy received bytes
			dmsg->plen -= b->last - b->pos;

			return;
		} else if (r->dyn_state == DYN_POST_DONE) {
			struct mbuf *last_buf = STAILQ_LAST(&r->mhdr, mbuf, next);
			if (last_buf->read_flip == 1) {
				data_store_parse_req(r);
			} else {
				r->result = MSG_PARSE_AGAIN;
			}
			return;
		}

		if (dmsg->type == GOSSIP_SYN) {
			//TODOs: need to address multi-buffer msg later
			dmsg->payload = b->pos;

			b->pos = b->pos + dmsg->plen;
			r->pos = b->pos;

			done_parsing = true;
		}

		if (done_parsing)
			return;

		return data_store_parse_req(r);
	}

	//bad case
	if (log_loggable(LOG_VVERB)) {
		log_debug(LOG_VVERB, "Bad or splitted message");  //fix me to do something
		msg_dump(r);
	}
	r->result = MSG_PARSE_AGAIN;
}
Ejemplo n.º 19
0
/*
 * copy one response from src to dst
 * return bytes copied
 * */
static rstatus_t
memcache_copy_bulk(struct msg *dst, struct msg *src)
{
    struct mbuf *mbuf, *nbuf;
    uint8_t *p;
    uint32_t len = 0;
    uint32_t bytes = 0;
    uint32_t i = 0;

    for (mbuf = STAILQ_FIRST(&src->mhdr);
         mbuf && mbuf_empty(mbuf);
         mbuf = STAILQ_FIRST(&src->mhdr)) {

        mbuf_remove(&src->mhdr, mbuf);
        mbuf_put(mbuf);
    }

    mbuf = STAILQ_FIRST(&src->mhdr);
    if (mbuf == NULL) {
        return NC_OK;           /* key not exists */
    }
    p = mbuf->pos;

    /* get : VALUE key 0 len\r\nval\r\n */
    /* gets: VALUE key 0 len cas\r\nval\r\n */

    ASSERT(*p == 'V');
    for (i = 0; i < 3; i++) {                 /*  eat 'VALUE key 0 '  */
        for (; *p != ' ';) {
            p++;
        }
        p++;
    }

    len = 0;
    for (; p < mbuf->last && isdigit(*p); p++) {
        len = len * 10 + (uint32_t)(*p - '0');
    }

    for (; p < mbuf->last && ('\r' != *p); p++) { /* eat cas for gets */
        ;
    }

    len += CRLF_LEN * 2;
    len += (p - mbuf->pos);

    bytes = len;

    /* copy len bytes to dst */
    for (; mbuf;) {
        if (mbuf_length(mbuf) <= len) {   /* steal this mbuf from src to dst */
            nbuf = STAILQ_NEXT(mbuf, next);
            mbuf_remove(&src->mhdr, mbuf);
            mbuf_insert(&dst->mhdr, mbuf);
            len -= mbuf_length(mbuf);
            mbuf = nbuf;
        } else {                        /* split it */
            nbuf = mbuf_get();
            if (nbuf == NULL) {
                return NC_ENOMEM;
            }
            mbuf_copy(nbuf, mbuf->pos, len);
            mbuf_insert(&dst->mhdr, nbuf);
            mbuf->pos += len;
            break;
        }
    }

    dst->mlen += bytes;
    src->mlen -= bytes;
    log_debug(LOG_VVERB, "memcache_copy_bulk copy bytes: %d", bytes);
    return NC_OK;
}
Ejemplo n.º 20
0
/* dnode sends a response back to a peer  */
struct msg *
dnode_rsp_send_next(struct context *ctx, struct conn *conn)
{
    if (TRACING_LEVEL == LOG_VVERB) {
	   log_debug(LOG_VVERB, "dnode_rsp_send_next entering");
    }

	ASSERT(conn->dnode_client && !conn->dnode_server);
	struct msg *msg = rsp_send_next(ctx, conn);

	if (msg != NULL && conn->dyn_mode) {
		struct msg *pmsg = TAILQ_FIRST(&conn->omsg_q); //peer request's msg

		//need to deal with multi-block later
		uint64_t msg_id = pmsg->dmsg->id;

		struct mbuf *header_buf = mbuf_get();
		if (header_buf == NULL) {
			loga("Unable to obtain an mbuf for header!");
			return NULL; //need to address error here properly
		}

		//TODOs: need to set the outcoming conn to be secured too if the incoming conn is secured
		if (pmsg->owner->dnode_secured || conn->dnode_secured) {
		    if (TRACING_LEVEL == LOG_VVERB) {
		       log_debug(LOG_VVERB, "Encrypting response ...");
			   loga("AES encryption key: %s\n", base64_encode(conn->aes_key, AES_KEYLEN));
            }
			struct mbuf *data_buf = STAILQ_LAST(&msg->mhdr, mbuf, next);

			//if (ENCRYPTION) {
			   struct mbuf *encrypted_buf = mbuf_get();
			   if (encrypted_buf == NULL) {
				  loga("Unable to obtain an mbuf for encryption!");
				  return NULL; //TODOs: need to clean up
			   }

			   rstatus_t status = dyn_aes_encrypt(data_buf->pos, mbuf_length(data_buf),
					   encrypted_buf, conn->aes_key);

		       if (TRACING_LEVEL == LOG_VVERB) {
			      log_debug(LOG_VERB, "#encrypted bytes : %d", status);
               }

			   dmsg_write(header_buf, msg_id, DMSG_RES, conn, mbuf_length(encrypted_buf));

		       if (TRACING_LEVEL == LOG_VVERB) {
			      log_hexdump(LOG_VVERB, data_buf->pos, mbuf_length(data_buf), "resp dyn message - original payload: ");
			      log_hexdump(LOG_VVERB, encrypted_buf->pos, mbuf_length(encrypted_buf), "dyn message encrypted payload: ");
               }

		       mbuf_copy(header_buf, encrypted_buf->start, mbuf_length(encrypted_buf));
			   mbuf_insert(&msg->mhdr, header_buf);
			   //remove the original dbuf out of the queue and insert encrypted mbuf to replace
			   mbuf_remove(&msg->mhdr, data_buf);
			   //mbuf_insert(&msg->mhdr, encrypted_buf);
			   mbuf_put(data_buf);
			   mbuf_put(encrypted_buf);
			//} else {
			//   log_debug(LOG_VERB, "no encryption on the response's payload");
			//   dmsg_write(header_buf, msg_id, DMSG_RES, conn, mbuf_length(data_buf));
			//}

		} else {
			dmsg_write(header_buf, msg_id, DMSG_RES, conn, 0);//Dont care about 0 or the real length as we don't use that value in unencryption mode
			mbuf_insert_head(&msg->mhdr, header_buf);
		}



	    if (TRACING_LEVEL == LOG_VVERB) {
		   log_hexdump(LOG_VVERB, header_buf->pos, mbuf_length(header_buf), "resp dyn message - header: ");
		   msg_dump(msg);
        }

	}

	return msg;
}
Ejemplo n.º 21
0
uint8_t
dns_get_seeds(struct context * ctx, struct mbuf *seeds_buf) 
{
    static int _env_checked = 0;

    if (!_env_checked) {
        _env_checked = 1;
        txtName = getenv("DYNOMITE_DNS_TXT_NAME");
        if (txtName == NULL)  txtName = DNS_TXT_NAME;
    }

    log_debug(LOG_VVERB, "checking for %s", txtName);

    if (!seeds_check()) {
        return DN_NOOPS;
    }

    unsigned char buf[BUFSIZ];
    int r = res_query(txtName, C_IN, T_TXT, buf, sizeof(buf));
    if (r == -1) {
        log_debug(LOG_DEBUG, "DNS response for %s: %s", txtName, hstrerror(h_errno));
        return DN_NOOPS;
    }
    if (r >= sizeof(buf)) {
        log_debug(LOG_DEBUG, "DNS reply is too large for %s: %d, bufsize: %d", txtName, r, sizeof(buf));
        return DN_NOOPS;
    }
    HEADER *hdr = (HEADER*)buf;
    if (hdr->rcode != NOERROR) {
        log_debug(LOG_DEBUG, "DNS reply code for %s: %d", txtName, hdr->rcode);
        return DN_NOOPS;
    }
    int na = ntohs(hdr->ancount);

    ns_msg m;
    int k = ns_initparse(buf, r, &m);
    if (k == -1) {
        log_debug(LOG_DEBUG, "ns_initparse error for %s: %s", txtName, strerror(errno));
        return DN_NOOPS;
    }
    int i;
    ns_rr rr;
    for (i = 0; i < na; ++i) {
        int k = ns_parserr(&m, ns_s_an, i, &rr);
        if (k == -1) {
            log_debug(LOG_DEBUG, "ns_parserr for %s: %s", txtName, strerror (errno));
            return DN_NOOPS;
        }
        mbuf_rewind(seeds_buf);
        unsigned char *r = ns_rr_rdata(rr);
        if (r[0] >= ns_rr_rdlen(rr)) {
            log_debug(LOG_DEBUG, "invalid TXT length for %s: %d < %d", txtName, r[0], ns_rr_rdlen(rr));
            return DN_NOOPS;
        }
        log_debug(LOG_VERB, "seeds for %s: %.*s", txtName, r[0], r +1);
        mbuf_copy(seeds_buf, r + 1, r[0]);
    }

    uint32_t seeds_hash = hash_seeds(seeds_buf->pos, mbuf_length(seeds_buf));
    if (last_seeds_hash != seeds_hash) {
        last_seeds_hash = seeds_hash;
    } else {
        return DN_NOOPS;
    }
    return DN_OK;
}