示例#1
0
static void client_handler(struct mg_connection *conn, int ev, void *p) {
  struct mbuf *io = &conn->recv_mbuf;
  (void) p;

  if (ev == MG_EV_CONNECT) {
    if (conn->flags & MG_F_CLOSE_IMMEDIATELY) {
      printf("%s\n", "Error connecting to server!");
      exit(EXIT_FAILURE);
    }
    printf("%s\n", "Connected to server. Type a message and press enter.");
  } else if (ev == MG_EV_RECV) {
    if (conn->flags & MG_F_USER_1) {
      // Received data from the stdin, forward it to the server
      struct mg_connection *c = (struct mg_connection *) conn->user_data;
      mg_send(c, io->buf, io->len);
      mbuf_remove(io, io->len);
    } else {
      // Received data from server connection, print it
      fwrite(io->buf, io->len, 1, stdout);
      mbuf_remove(io, io->len);
    }
  } else if (ev == MG_EV_CLOSE) {
    // Connection has closed, most probably cause server has stopped
    exit(EXIT_SUCCESS);
  }
}
示例#2
0
void conn_handler(struct mg_connection *nc, int ev, void *arg) {
  struct conn_ctx *ctx = (struct conn_ctx *) nc->user_data;
  struct mbuf *io = &nc->recv_mbuf;
  switch (ev) {
    case NS_POLL:
      break;
    case NS_CONNECT: {
      printf("connected\n");
      ctx->state = CONNECTED;
      do_send(nc);
      break;
    }
    case NS_RECV:
      ctx->num_received += io->len;
      mbuf_remove(io, io->len);
      break;
    case NS_SEND: {
      do_send(nc);
      ctx->num_sent += *((int *) arg);
      break;
    }
    case NS_CLOSE: {
      printf("disconnected\n");
      ctx->state = DISCONNECTED;
      break;
    }
  }
}
示例#3
0
void mg_lwip_ssl_send(struct mg_connection *nc) {
  if (nc->sock == INVALID_SOCKET) {
    DBG(("%p invalid socket", nc));
    return;
  }
  struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock;
  /* It's ok if the buffer is empty. Return value of 0 may also be valid. */
  int len = cs->last_ssl_write_size;
  if (len == 0) {
    len = MIN(MG_LWIP_SSL_IO_SIZE, nc->send_mbuf.len);
  }
  int ret = SSL_write(nc->ssl, nc->send_mbuf.buf, len);
  int err = SSL_get_error(nc->ssl, ret);
  DBG(("%p SSL_write %u = %d, %d", nc, len, ret, err));
  if (ret > 0) {
    mbuf_remove(&nc->send_mbuf, ret);
    mbuf_trim(&nc->send_mbuf);
    cs->last_ssl_write_size = 0;
  } else if (ret < 0) {
    /* This is tricky. We must remember the exact data we were sending to retry
     * exactly the same send next time. */
    cs->last_ssl_write_size = len;
  }
  if (err == SSL_ERROR_NONE) {
    nc->flags &= ~MG_F_WANT_WRITE;
  } else if (err == SSL_ERROR_WANT_WRITE) {
    nc->flags |= MG_F_WANT_WRITE;
  } else {
    LOG(LL_ERROR, ("SSL write error: %d", err));
    mg_lwip_post_signal(MG_SIG_CLOSE_CONN, nc);
  }
}
示例#4
0
static void mg_lwip_tcp_write(struct mg_connection *nc) {
  struct tcp_pcb *tpcb = (struct tcp_pcb *) nc->sock;
  size_t len;
  if (nc->sock == INVALID_SOCKET) {
    DBG(("%p tcp_write invalid socket %d", nc, nc->err));
    return;
  }
  len = MIN(tpcb->mss, MIN(nc->send_mbuf.len, tpcb->snd_buf));
  if (len == 0) {
    DBG(("%p no buf avail %u %u %u %p %p", nc, tpcb->acked, tpcb->snd_buf,
         tpcb->snd_queuelen, tpcb->unsent, tpcb->unacked));
    tcp_output(tpcb);
    return;
  }
  nc->err = tcp_write(tpcb, nc->send_mbuf.buf, len, TCP_WRITE_FLAG_COPY);
  tcp_output(tpcb);
  DBG(("%p tcp_write %u = %d", nc, len, nc->err));
  if (nc->err != ERR_OK) {
    if (nc->err != ERR_MEM) {
      system_os_post(MG_TASK_PRIORITY, MG_SIG_CLOSE_CONN, (uint32_t) nc);
    }
    /*
     * We ignore ERR_MEM because memory will be freed up when the data is sent
     * and we'll retry.
     */
  } else {
    mbuf_remove(&nc->send_mbuf, len);
    mbuf_trim(&nc->send_mbuf);
  }
}
示例#5
0
static int console_send_file(struct v7 *v7, struct cache *cache) {
  int ret = 0;
  char *logs = NULL;
  size_t size = 0;
  if (cache->file_names.len != 0) {
    logs = cs_read_file(cache->file_names.buf, &size);
    if (logs == NULL) {
      LOG(LL_ERROR, ("Failed to read from %s", cache->file_names.buf));
      ret = -1;
      goto clean;
    }

    console_make_clubby_call(v7, logs);

    remove(cache->file_names.buf);
    mbuf_remove(&cache->file_names, FILENAME_LEN);
  }

clean:
  if (logs != NULL) {
    free(logs);
  }

  return ret;
}
示例#6
0
void cc3200_console_cloud_putc(char c) {
  if (s_cctx.in_console || !s_cctx.initialized) return;
  s_cctx.in_console = 1;
  /* If console is overfull, drop old message(s). */
  int max_buf = get_cfg()->console.mem_cache_size;
  while (s_cctx.buf.len >= max_buf) {
    int l = cc3200_console_next_msg_len();
    if (l == 0) {
      l = s_cctx.buf.len;
      s_cctx.msg_in_progress = 0;
    }
    mbuf_remove(&s_cctx.buf, l);
  }
  /* Construct valid JSON from the get-go. */
  if (!s_cctx.msg_in_progress) {
    /* Skip empty lines */
    if (c == '\n') goto out;
    mbuf_append(&s_cctx.buf, "{\"msg\":\"", 8);
    s_cctx.msg_in_progress = 1;
  }
  if (c == '"' || c == '\\') {
    mbuf_append(&s_cctx.buf, "\\", 1);
  }
  if (c >= 0x20) mbuf_append(&s_cctx.buf, &c, 1);
  if (c == '\n') {
    mbuf_append(&s_cctx.buf, "\"}\n", 3);
    s_cctx.msg_in_progress = 0;
  }
out:
  s_cctx.in_console = 0;
}
示例#7
0
void sj_conf_emit_f_cb(struct mbuf *data, void *param) {
  FILE **fp = (FILE **) param;
  if (*fp != NULL && fwrite(data->buf, 1, data->len, *fp) != data->len) {
    LOG(LL_ERROR, ("Error writing file\n"));
    fclose(*fp);
    *fp = NULL;
  }
  mbuf_remove(data, data->len);
}
示例#8
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;

}
示例#9
0
void
mbuf_deinit(void)
{
    while (!STAILQ_EMPTY(&free_mbufq)) {
        struct mbuf *mbuf = STAILQ_FIRST(&free_mbufq);
        mbuf_remove(&free_mbufq, mbuf);
        mbuf_free(mbuf);
        nfree_mbufq--;
    }
    ASSERT(nfree_mbufq == 0);
}
示例#10
0
void mgos_uart_hal_dispatch_tx_top(struct mgos_uart_state *us) {
  struct cc32xx_uart_state *ds = (struct cc32xx_uart_state *) us->dev_data;
  struct mbuf *txb = &us->tx_buf;
  size_t len = 0;
  while (len < txb->len && MAP_UARTSpaceAvail(ds->base)) {
    HWREG(ds->base + UART_O_DR) = *(txb->buf + len);
    len++;
  }
  mbuf_remove(txb, len);
  us->stats.tx_bytes += len;
  MAP_UARTIntClear(ds->base, UART_TX_INTS);
}
示例#11
0
static void ev_handler(struct mg_connection *nc, int ev, void *p) {
  struct mbuf *io = &nc->recv_mbuf;
  (void) p;

  switch (ev) {
    case MG_EV_RECV:
      mg_send(nc, io->buf, io->len);  // Echo message back
      mbuf_remove(io, io->len);       // Discard message from recv buffer
      break;
    default:
      break;
  }
}
示例#12
0
void
mbuf_deinit(void)
{
    while (!STAILQ_EMPTY(&free_mbufq)) {
        struct mbuf *mbuf = STAILQ_FIRST(&free_mbufq);
        mbuf_remove(&free_mbufq, mbuf);
        mbuf_free(mbuf);
        nfree_mbufq--;
		
#if 1 //shenzheng 2015-3-23 common
#ifdef NC_DEBUG_LOG
		ntotal_mbuf--;
#endif
#endif //shenzheng 2015-3-23 common

    }

#if 1 //shenzheng 2015-5-13 proxy administer
	while (!STAILQ_EMPTY(&free_mbufq_proxy_adm)) {
        struct mbuf *mbuf = STAILQ_FIRST(&free_mbufq_proxy_adm);
        mbuf_remove(&free_mbufq_proxy_adm, mbuf);
        mbuf_free(mbuf);
        nfree_mbufq_proxy_adm--;

#ifdef NC_DEBUG_LOG
		ntotal_mbuf_proxy_adm--;
#endif
	}
#endif //shenzheng 2015-5-13 proxy administer

    ASSERT(nfree_mbufq == 0);
	
#if 1 //shenzheng 2015-3-23 common
#ifdef NC_DEBUG_LOG
	ASSERT(ntotal_mbuf == 0);
#endif
#endif //shenzheng 2015-3-23 common

}
示例#13
0
rstatus_t
conn_close(struct conn *conn)
{
    rstatus_t status;
    struct mbuf *mbuf, *nbuf;            /* current and next mbuf */

    if (conn->fd < 0) {
        conn_put(conn);
        return NC_OK;
    }

    if (!STAILQ_EMPTY(&conn->recv_queue)) {
        log_warn("close conn %d discard data in send_queue", conn->fd);
        for (mbuf = STAILQ_FIRST(&conn->recv_queue); mbuf != NULL; mbuf = nbuf) {
            nbuf = STAILQ_NEXT(mbuf, next);
            mbuf_remove(&conn->recv_queue, mbuf);
            mbuf_put(mbuf);
        }
    }

    if (!STAILQ_EMPTY(&conn->send_queue)) {
        log_warn("close conn %d discard data in send_queue", conn->fd);
        for (mbuf = STAILQ_FIRST(&conn->send_queue); mbuf != NULL; mbuf = nbuf) {
            nbuf = STAILQ_NEXT(mbuf, next);
            mbuf_remove(&conn->send_queue, mbuf);
            mbuf_put(mbuf);
        }
    }

    status = close(conn->fd);
    if (status < 0) {
        log_error("close c %d failed, ignored: %s", conn->fd, strerror(errno));
    }
    conn->fd = -1;

    conn_put(conn);
    return NC_OK;
}
示例#14
0
static void mg_lwip_send_more(struct mg_connection *nc) {
  struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock;
  if (nc->sock == INVALID_SOCKET || cs->pcb.tcp == NULL) {
    DBG(("%p invalid socket", nc));
    return;
  }
  int num_written = mg_lwip_tcp_write(nc, nc->send_mbuf.buf, nc->send_mbuf.len);
  DBG(("%p mg_lwip_tcp_write %u = %d", nc, nc->send_mbuf.len, num_written));
  if (num_written == 0) return;
  if (num_written < 0) {
    mg_lwip_post_signal(MG_SIG_CLOSE_CONN, nc);
  }
  mbuf_remove(&nc->send_mbuf, num_written);
  mbuf_trim(&nc->send_mbuf);
}
示例#15
0
static void forward_body(struct peer *src, struct peer *dst) {
    struct mbuf *src_io = &src->nc->recv_mbuf;
    if (src->body_sent < src->body_len) {
        size_t to_send = src->body_len - src->body_sent;
        if (src_io->len < to_send) {
            to_send = src_io->len;
        }
        ns_send(dst->nc, src_io->buf, to_send);
        src->body_sent += to_send;
        mbuf_remove(src_io, to_send);
    }
#ifdef DEBUG
    write_log("forward_body %p (ka=%d) -> %p sent %d of %d\n", src->nc,
              src->flags.keep_alive, dst->nc, src->body_sent, src->body_len);
#endif
}
示例#16
0
文件: net.c 项目: xuezaijiongtu/fossa
static void ns_write_to_socket(struct ns_connection *conn) {
  struct mbuf *io = &conn->send_mbuf;
  int n = 0;

  assert(io->len > 0);

#ifdef NS_ENABLE_SSL
  if (conn->ssl != NULL) {
    if (conn->flags & NSF_SSL_HANDSHAKE_DONE) {
      n = SSL_write(conn->ssl, io->buf, io->len);
      if (n <= 0) {
        int ssl_err = ns_ssl_err(conn, n);
        if (ssl_err == SSL_ERROR_WANT_READ || ssl_err == SSL_ERROR_WANT_WRITE) {
          return; /* Call us again */
        } else {
          conn->flags |= NSF_CLOSE_IMMEDIATELY;
        }
      } else {
        /* Successful SSL operation, clear off SSL wait flags */
        conn->flags &= ~(NSF_WANT_READ | NSF_WANT_WRITE);
      }
    } else {
      ns_ssl_begin(conn);
      return;
    }
  } else
#endif
  {
    n = (int) NS_SEND_FUNC(conn->sock, io->buf, io->len, 0);
  }

  DBG(("%p %d bytes -> %d", conn, n, conn->sock));

  if (ns_is_error(n)) {
    conn->flags |= NSF_CLOSE_IMMEDIATELY;
  } else if (n > 0) {
#ifndef NS_DISABLE_FILESYSTEM
    /* LCOV_EXCL_START */
    if (conn->mgr->hexdump_file != NULL) {
      ns_hexdump_connection(conn, conn->mgr->hexdump_file, n, NS_SEND);
    }
/* LCOV_EXCL_STOP */
#endif
    mbuf_remove(io, n);
  }
  ns_call(conn, NS_SEND, &n);
}
示例#17
0
static void context_remove_data(struct update_context *ctx, size_t len) {
  LOG(LL_DEBUG, ("Removing %d bytes", len));

  if (ctx->unprocessed.len != 0) {
    /* Consumed data from unprocessed*/
    mbuf_remove(&ctx->unprocessed, len);
    ctx->data = ctx->unprocessed.buf;
    ctx->data_len = ctx->unprocessed.len;
    LOG(LL_DEBUG, ("Removed %d bytes from cached data", len));
  } else {
    /* Consumed received data */
    ctx->data = ctx->data + len;
    ctx->data_len -= len;
  }

  LOG(LL_DEBUG, ("Data size: %u bytes", ctx->data_len));
}
示例#18
0
static void mg_lwip_send_more(struct mg_connection *nc) {
  struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock;
  if (nc->sock == INVALID_SOCKET || cs->pcb.tcp == NULL) {
    DBG(("%p invalid socket", nc));
    return;
  }
  struct tcp_pcb *tpcb = cs->pcb.tcp;
  int num_written =
      mg_lwip_tcp_write(tpcb, nc->send_mbuf.buf, nc->send_mbuf.len);
  DBG(("%p mg_lwip_tcp_write %u = %d", nc, nc->send_mbuf.len, num_written));
  if (num_written == 0) return;
  if (num_written < 0) {
    system_os_post(MG_TASK_PRIORITY, MG_SIG_CLOSE_CONN, (uint32_t) nc);
  }
  mbuf_remove(&nc->send_mbuf, num_written);
  mbuf_trim(&nc->send_mbuf);
}
示例#19
0
static void prompt_handler(struct ns_connection *nc, int ev, void *ev_data) {
  size_t i;
  struct mbuf *io = &nc->recv_mbuf;
  switch (ev) {
    case NS_RECV:
      for (i = 0; i < io->len; i++) {
        sj_prompt_process_char(io->buf[i]);
        if (io->buf[i] == '\n') {
          sj_prompt_process_char('\r');
        }
      }
      mbuf_remove(io, io->len);
      break;
    case NS_CLOSE:
      sj_please_quit = 1;
      break;
  }
}
示例#20
0
void mgos_uart_hal_dispatch_tx_top(struct mgos_uart_state *us) {
  int uart_no = us->uart_no;
  struct mbuf *txb = &us->tx_buf;
  uint32_t txn = 0;
  /* TX */
  if (txb->len > 0) {
    while (txb->len > 0) {
      size_t tx_av = 128 - esp_uart_tx_fifo_len(uart_no);
      size_t len = MIN(txb->len, tx_av);
      if (len == 0) break;
      for (size_t i = 0; i < len; i++) {
        esp_uart_tx_byte(uart_no, *(txb->buf + i));
      }
      txn += len;
      mbuf_remove(txb, len);
    }
    us->stats.tx_bytes += txn;
  }
}
示例#21
0
void cc3200_console_cloud_push() {
  if (s_cctx.buf.len == 0 || !s_cctx.initialized) return;
  int l = cc3200_console_next_msg_len();
  if (l == 0) return;  // Only send full messages.
  struct clubby *c = sj_clubby_get_global();
  if (c == NULL || !sj_clubby_is_connected(c)) {
    /* If connection drops, do not wait for reply as it may never arrive. */
    s_cctx.request_in_flight = 0;
    return;
  }
  if (s_cctx.request_in_flight || !sj_clubby_can_send(c)) return;
  s_cctx.request_in_flight = 1;
  s_cctx.in_console = 1;
  sj_clubby_call(c, NULL, "/v1/Log.Log", mg_mk_str_n(s_cctx.buf.buf, l - 1), 0,
                 clubby_cb, NULL);
  mbuf_remove(&s_cctx.buf, l);
  if (s_cctx.buf.len == 0) mbuf_trim(&s_cctx.buf);
  s_cctx.in_console = 0;
}
示例#22
0
static void server_handler(struct mg_connection *nc, int ev, void *p) {
  (void) p;
  if (ev == MG_EV_RECV) {
    // Push received message to all ncections
    struct mbuf *io = &nc->recv_mbuf;
    struct mg_connection *c;

    for (c = mg_next(nc->mgr, NULL); c != NULL; c = mg_next(nc->mgr, c)) {
      if (!(c->flags |= MG_F_USER_2)) continue;  // Skip non-client connections
      mg_send(c, io->buf, io->len);
    }
    mbuf_remove(io, io->len);
  } else if (ev == MG_EV_ACCEPT) {
    char addr[32];
    mg_sock_addr_to_str(p, addr, sizeof(addr),
                        MG_SOCK_STRINGIFY_IP | MG_SOCK_STRINGIFY_PORT);
    printf("New client connected from %s\n", addr);
  }
}
示例#23
0
static void mg_lwip_ssl_send(struct mg_connection *nc) {
  if (nc->sock == INVALID_SOCKET) {
    DBG(("%p invalid socket", nc));
    return;
  }
  /* It's ok if the buffer is empty. Return value of 0 may also be valid. */
  int ret = SSL_write(nc->ssl, nc->send_mbuf.buf, nc->send_mbuf.len);
  int err = SSL_get_error(nc->ssl, ret);
  DBG(("%p SSL_write %u = %d, %d", nc, nc->send_mbuf.len, ret, err));
  if (ret > 0) {
    mbuf_remove(&nc->send_mbuf, ret);
    mbuf_trim(&nc->send_mbuf);
  }
  if (err == SSL_ERROR_NONE) {
    nc->flags &= ~MG_F_WANT_WRITE;
  } else if (err == SSL_ERROR_WANT_WRITE) {
    nc->flags |= MG_F_WANT_WRITE;
  } else {
    LOG(LL_ERROR, ("SSL write error: %d", err));
    system_os_post(MG_TASK_PRIORITY, MG_SIG_CLOSE_CONN, (uint32_t) nc);
  }
}
示例#24
0
static rstatus_t
conn_send_queue(struct conn *conn)
{
    struct mbuf *mbuf, *nbuf;                   /* current and next mbuf */
    size_t mlen;                                /* current mbuf data length */
    ssize_t n;

    for (mbuf = STAILQ_FIRST(&conn->send_queue); mbuf != NULL; mbuf = nbuf) {
        nbuf = STAILQ_NEXT(mbuf, next);

        if (mbuf_empty(mbuf)) {
            continue;
        }

        mlen = mbuf_length(mbuf);
        n = conn_send_buf(conn, mbuf->pos, mlen);

        if (n < 0) {
            if (n == NC_EAGAIN) {
                return NC_OK;
            }
            return NC_ERROR;
        }

        mbuf->pos += n;
        if (n < mlen) {
            ASSERT(mbuf->pos < mbuf->end);
            return NC_OK;
        }

        ASSERT(mbuf->pos == mbuf->last);

        mbuf_remove(&conn->send_queue, mbuf);
        mbuf_put(mbuf);
    }

    conn->send_ready = 0;
    return NC_OK;
}
/* 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;
}
示例#26
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;
}
示例#27
0
static void forward(struct conn_data *conn, struct http_message *hm,
                    struct peer *src_peer, struct peer *dst_peer) {
    struct ns_connection *src = src_peer->nc;
    struct ns_connection *dst = dst_peer->nc;
    struct mbuf *io = &src->recv_mbuf;
    int i;
    int is_request = (src_peer == &conn->client);
    src_peer->body_len = hm->body.len;
    struct http_backend *be = conn->be_conn->be;

    if (is_request) {
        /* Write rewritten request line. */
        size_t trim_len = strlen(be->uri_prefix);
        ns_printf(dst, "%.*s%s%.*s\r\n", (int) (hm->uri.p - io->buf), io->buf,
                  be->uri_prefix_replacement,
                  (int) (hm->proto.p + hm->proto.len - (hm->uri.p + trim_len)),
                  hm->uri.p + trim_len);
    } else {
        /* Reply line goes without modification */
        ns_printf(dst, "%.*s %d %.*s\r\n", (int) hm->proto.len, hm->proto.p,
                  (int) hm->resp_code, (int) hm->resp_status_msg.len,
                  hm->resp_status_msg.p);
    }

    /* Headers. */
    for (i = 0; i < NS_MAX_HTTP_HEADERS && hm->header_names[i].len > 0; i++) {
        struct ns_str hn = hm->header_names[i];
        struct ns_str hv = hm->header_values[i];
#ifdef NS_ENABLE_SSL
        /*
         * If we terminate SSL and backend redirects to local HTTP port,
         * strip protocol to let client use HTTPS.
         * TODO(lsm): web page content may also contain local HTTP references,
         * they need to be rewritten too.
         */
        if (ns_vcasecmp(&hn, "Location") == 0 && s_ssl_cert != NULL) {
            size_t hlen = strlen(be->host_port);
            const char *hp = be->host_port, *p = memchr(hp, ':', hlen);

            if (p == NULL) {
                p = hp + hlen;
            }

            if (ns_ncasecmp(hv.p, "http://", 7) == 0 &&
                    ns_ncasecmp(hv.p + 7, hp, (p - hp)) == 0) {
                ns_printf(dst, "Location: %.*s\r\n", (int) (hv.len - (7 + (p - hp))),
                          hv.p + 7 + (p - hp));
                continue;
            }
        }
#endif

        /* We always rewrite the connection header depending on the settings. */
        if (ns_vcasecmp(&hn, "Connection") == 0) continue;

        ns_printf(dst, "%.*s: %.*s\r\n", (int) hn.len, hn.p, (int) hv.len, hv.p);
    }

    /* Emit the connection header. */
    const char *connection_mode = "close";
    if (dst_peer == &conn->backend) {
        if (s_backend_keepalive) connection_mode = "keep-alive";
    } else {
        if (conn->client.flags.keep_alive) connection_mode = "keep-alive";
    }
    ns_printf(dst, "Connection: %s\r\n", connection_mode);

    ns_printf(dst, "%s", "\r\n");

    mbuf_remove(io, hm->body.p - hm->message.p); /* We've forwarded headers */
    dst_peer->flags.headers_sent = 1;

    forward_body(src_peer, dst_peer);
}
示例#28
0
static bool 
dyn_parse_core(struct msg *r)
{
   struct dmsg *dmsg;
   struct mbuf *b;
   uint8_t *p, *token;
   uint8_t ch = ' ';
   uint64_t num = 0;

   dyn_state = r->dyn_state;
   if (log_loggable(LOG_DEBUG)) {
      log_debug(LOG_DEBUG, "dyn_state:  %d", r->dyn_state);
   }

   if (r->dyn_state == DYN_DONE || r->dyn_state == DYN_POST_DONE)
       return true;

   b = STAILQ_LAST(&r->mhdr, mbuf, next);

   dmsg = r->dmsg;
   if (dmsg == NULL) {
      r->dmsg = dmsg_get();
      dmsg = r->dmsg;
      dmsg->owner = r;
      if (dmsg == NULL) {//should track this as a dropped message
         loga("unable to create a new dmsg");
         goto error; //should count as OOM error
      }
   }

   token = NULL;

   for (p = r->pos; p < b->last; p++) {
      ch = *p;
      switch (dyn_state) {
      case DYN_START:
         if (log_loggable(LOG_DEBUG)) {
            log_debug(LOG_DEBUG, "DYN_START");
         }
         if (ch != ' ' && ch != '$') {
            break;
         }

         if (ch == ' ') {
            if (token == NULL)
               token = p;

            break;
         }

         if (ch == '$') {
              if (p + 5 < b->last) {
                  if ((*(p+1) == '2') &&
                      (*(p+2) == '0') &&
                      (*(p+3) == '1') &&
                      (*(p+4) == '4') &&
                      (*(p+5) == '$')) {
                     dyn_state = DYN_MAGIC_STRING;
                     p += 5;
                  } else {
                     //goto skip;
                     token = NULL; //reset
                  }
              } else {
                    goto split;
              }
         } else {
            loga("Facing a weird char %c", p);
            //goto skip;
            token = NULL; //reset
         }

         break;

      case DYN_MAGIC_STRING:
         if (log_loggable(LOG_DEBUG)) {
            log_debug(LOG_DEBUG, "DYN_MAGIC_STRING");
         }
         if (ch == ' ') {
            dyn_state = DYN_MSG_ID;
            num = 0;
            break;
         } else {
            //loga("char is '%c %c %c %c'", *(p-2), *(p-1), ch, *(p+1));
            token = NULL;
            loga("Facing a weird char %c", p);
            //goto skip;
            dyn_state = DYN_START;
         }

         break;

      case DYN_MSG_ID:
         if (log_loggable(LOG_DEBUG)) {
            log_debug(LOG_DEBUG, "DYN_MSG_ID");
            log_debug(LOG_DEBUG, "num = %d", num);
         }
         if (isdigit(ch))  {
            num = num*10 + (ch - '0');
         } else if (ch == ' ' && isdigit(*(p-1)))  {
            if (log_loggable(LOG_DEBUG)) {
               log_debug(LOG_DEBUG, "MSG ID : %d", num);
            }
            dmsg->id = num;
            dyn_state = DYN_TYPE_ID;
            num = 0;
         } else {
            //loga("char is '%c %c %c %c'", *(p-2), *(p-1), ch, *(p+1));
            //goto skip;
            token = NULL; //reset
            dyn_state = DYN_START;
            if (ch == '$')
               p -= 1;
         }
         break;

      case DYN_TYPE_ID:
         if (log_loggable(LOG_DEBUG)) {
            log_debug(LOG_DEBUG, "DYN_TYPE_ID: num = %d", num);
         }
         if (isdigit(ch))  {
            num = num*10 + (ch - '0');
         } else if (ch == ' ' && isdigit(*(p-1)))  {
            if (log_loggable(LOG_DEBUG)) {
               log_debug(LOG_DEBUG, "Type Id: %d", num);
            }
            dmsg->type = num;
            dyn_state = DYN_BIT_FIELD;
            num = 0;
         } else {
            //loga("char is '%c %c %c %c'", *(p-2), *(p-1), ch, *(p+1));
            token = NULL;
            dyn_state = DYN_START;
            if (ch == '$')
               p -= 1;
         }

         break;

      case DYN_BIT_FIELD:
         if (log_loggable(LOG_DEBUG)) {
            log_debug(LOG_DEBUG, "DYN_BIT_FIELD, num = %d", num);
         }
         if (isdigit(ch))  {
            num = num*10 + (ch - '0');
         } else if (ch == ' ' && isdigit(*(p-1)))  {
            if (log_loggable(LOG_DEBUG)) {
               log_debug(LOG_DEBUG, "DYN_BIT_FIELD : %d", num);
            }
            dmsg->bit_field = num & 0xF;
            dyn_state = DYN_VERSION;
            num = 0;
         } else {
            token = NULL;
            //loga("char is '%c %c %c %c'", *(p-2), *(p-1), ch, *(p+1));
            dyn_state = DYN_START;
            if (ch == '$')
               p -= 1;
         }

         break;

      case DYN_VERSION:
         if (log_loggable(LOG_DEBUG)) {
            log_debug(LOG_DEBUG, "DYN_VERSION: num = %d", num);
         }
         if (isdigit(ch))  {
            num = num*10 + (ch - '0');
         } else if (ch == ' ' && isdigit(*(p-1)))  {
            if (log_loggable(LOG_DEBUG)) {
               log_debug(LOG_DEBUG, "VERSION : %d", num);
            }
            dmsg->version = num;
            dyn_state = DYN_SAME_DC;
            num = 0;
         } else {
            token = NULL;
            //loga("char is '%c %c %c %c'", *(p-2), *(p-1), ch, *(p+1));
            dyn_state = DYN_START;
            if (ch == '$')
               p -= 1;
         }

         break;

      case DYN_SAME_DC:
      	if (isdigit(ch)) {
      		dmsg->same_dc = ch - '0';
      		if (log_loggable(LOG_DEBUG)) {
           	   log_debug(LOG_DEBUG, "DYN_SAME_DC %d", dmsg->same_dc);
      		}
      	} else if (ch == ' ' && isdigit(*(p-1))) {
      		dyn_state = DYN_DATA_LEN;
      		num = 0;
      	} else {
      		token = NULL;
      		//loga("char is '%c %c %c %c'", *(p-2), *(p-1), ch, *(p+1));
      		dyn_state = DYN_START;
      		if (ch == '$')
      		   p -= 1;
      	}

      	break;

      case DYN_DATA_LEN:
         if (log_loggable(LOG_DEBUG)) {
            log_debug(LOG_DEBUG, "DYN_DATA_LEN: num = %d", num);
         }
         if (ch == '*') {
            break;
         } else if (isdigit(ch))  {
            num = num*10 + (ch - '0');
         } else if (ch == ' ' && isdigit(*(p-1)))  {
            if (log_loggable(LOG_DEBUG)) {
               log_debug(LOG_DEBUG, "Data len: %d", num);
            }
            dmsg->mlen = num;
            dyn_state = DYN_DATA;
            num = 0;
         } else {
            token = NULL;
            //loga("char is '%c %c %c %c'", *(p-2), *(p-1), ch, *(p+1));
            dyn_state = DYN_START;
            if (ch == '$')
               p -= 1;
         }
         break;

      case DYN_DATA:
         if (log_loggable(LOG_DEBUG)) {
            log_debug(LOG_DEBUG, "DYN_DATA");
         }
         if (p + dmsg->mlen < b->last) {
            dmsg->data = p;
            p += dmsg->mlen - 1;
            dyn_state = DYN_SPACES_BEFORE_PAYLOAD_LEN;
         } else {
            //loga("char is '%c %c %c %c'", *(p-2), *(p-1), ch, *(p+1));
            goto split;
         }

         break;

      case DYN_SPACES_BEFORE_PAYLOAD_LEN:
         if (log_loggable(LOG_DEBUG)) {
            log_debug(LOG_DEBUG, "DYN_SPACES_BEFORE_PAYLOAD_LEN");
         }
         if (ch == ' ') {
            break;
         } else if (ch == '*') {
            dyn_state = DYN_PAYLOAD_LEN;
            num = 0;
         }

         break;

      case DYN_PAYLOAD_LEN:

         if (isdigit(ch))  {
            num = num*10 + (ch - '0');
         } else if (ch == CR)  {
            if (log_loggable(LOG_DEBUG)) {
               log_debug(LOG_DEBUG, "Payload len: %d", num);
            }
            dmsg->plen = num;
            num = 0;
            dyn_state = DYN_CRLF_BEFORE_DONE;
         } else {
            token = NULL;
            dyn_state = DYN_START;
            if (ch == '$')
               p -= 1;
         }
         break;

      case DYN_CRLF_BEFORE_DONE:
         if (log_loggable(LOG_DEBUG)) {
            log_debug(LOG_DEBUG, "DYN_CRLF_BEFORE_DONE");
         }
         if (*p == LF) {
            dyn_state = DYN_DONE;
         } else {
            token = NULL;
            dyn_state = DYN_START;
            if (ch == '$')
               p -= 1;
         }

         break;

      case DYN_DONE:
         if (log_loggable(LOG_DEBUG)) {
            log_debug(LOG_DEBUG, "DYN_DONE");
         }
         r->pos = p;
         dmsg->payload = p;
         r->dyn_state = DYN_DONE;
         b->pos = p;
         goto done;
         break;

      default:
         NOT_REACHED();
         break;

      }

   }

   if (log_loggable(LOG_DEBUG)) {
      log_debug(LOG_DEBUG, "Not fully parsed yet!!!!!!");
   }
   split:
   //this is an attempt recovery when we got a bad message
   //we try to look for the start the next good one and throw away the bad part
   if (r->dyn_state == DYN_START) {
      r->result = MSG_PARSE_AGAIN;
       if (b->last == b->end) {
          struct mbuf *nbuf = mbuf_get();
          if (nbuf == NULL) {
             loga("Unable to obtain a new mbuf for replacement!");
             mbuf_put(b);
             nbuf = mbuf_get();
             mbuf_insert_head(&r->mhdr, nbuf);
             r->pos = nbuf->pos;
             return false;
         }

         //replacing the bad mbuf with a new and empty mbuf
         mbuf_insert(&r->mhdr, nbuf);
         mbuf_remove(&r->mhdr, b);
         mbuf_put(b);
         r->pos = nbuf->pos;
         return false;
       } else { //split it and throw away the bad portion
           struct mbuf *nbuf;

           nbuf = mbuf_split(&r->mhdr, r->pos, NULL, NULL);
          if (nbuf == NULL) {
               return DN_ENOMEM;
          }
          mbuf_insert(&r->mhdr, nbuf);
          mbuf_remove(&r->mhdr, b);
          r->pos = nbuf->pos;
          return false;
       }

   }

   if (mbuf_length(b) == 0 || b->last == b->end) {
      if (log_loggable(LOG_DEBUG)) {
          log_debug(LOG_DEBUG, "Would this case ever happen?");
      }
      r->result = MSG_PARSE_AGAIN;
      return false;
   }

   if (r->pos == b->last) {
       if (log_loggable(LOG_DEBUG)) {
           log_debug(LOG_DEBUG, "Forward to reading the new block of data");
       }
       r->dyn_state = DYN_START;
       r->result = MSG_PARSE_AGAIN;
       token = NULL;
       return false;
   }

   if (log_loggable(LOG_VVERB)) {
      log_debug(LOG_VVERB, "in split");
   }
   r->dyn_state = DYN_START;
   r->pos = token;
   r->result = MSG_PARSE_REPAIR;
   if (log_loggable(LOG_VVERB)) {
      log_hexdump(LOG_VVERB, b->pos, mbuf_length(b), "split and inspecting req %"PRIu64" "
            "res %d type %d state %d", r->id, r->result, r->type,
            r->dyn_state);

      log_hexdump(LOG_VVERB, b->start, b->last - b->start, "split and inspecting full req %"PRIu64" "
            "res %d type %d state %d", r->id, r->result, r->type,
            r->dyn_state);
   }
   return false;

   done:
   r->pos = p;
   dmsg->source_address = r->owner->addr;

   if (log_loggable(LOG_VVERB)) {
      log_debug(LOG_VVERB, "at done with p at %d", p);
      log_hexdump(LOG_VVERB, r->pos, b->last - r->pos, "done and inspecting req %"PRIu64" "
            "res %d type %d state %d", r->id, r->result, r->type,
            r->dyn_state);
      log_hexdump(LOG_VVERB, b->start, b->last - b->start, "inspecting req %"PRIu64" "
            "res %d type %d state %d", r->id, r->result, r->type,
            r->dyn_state);
   }

   return true;

   error:
   log_debug(LOG_ERR, "at error for state %d and c %c", dyn_state, *p);
   r->result = MSG_PARSE_ERROR;
   r->pos = p;
   errno = EINVAL;

   if (log_loggable(LOG_ERR)) {
      log_hexdump(LOG_ERR, b->pos, mbuf_length(b), "parsed bad req %"PRIu64" "
            "res %d type %d state %d", r->id, r->result, r->type,
            dyn_state);
      log_hexdump(LOG_ERR, p, b->last - p, "inspecting req %"PRIu64" "
            "res %d type %d state %d", r->id, r->result, r->type,
            dyn_state);
   }
   r->dyn_state = dyn_state;

   return false;
}
示例#29
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;
}
示例#30
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;

}