|
@@ -4,24 +4,97 @@
|
|
|
|
|
|
#include "or.h"
|
|
|
|
|
|
-int check_sane_cell(cell_t *cell) {
|
|
|
+static cell_t *new_create_cell(uint16_t aci, unsigned char length, unsigned char *buf)
|
|
|
+{
|
|
|
+ cell_t *c = NULL;
|
|
|
+ int retval;
|
|
|
|
|
|
- assert(cell);
|
|
|
+ if ((aci) && (buf) && (length <= CELL_PAYLOAD_SIZE)) /* valid parameters */
|
|
|
+ {
|
|
|
+ c = (cell_t *)malloc(sizeof(cell_t));
|
|
|
+ if (!c) /* malloc() error */
|
|
|
+ return NULL;
|
|
|
+
|
|
|
+ c->command = CELL_CREATE;
|
|
|
+ c->aci = aci;
|
|
|
+ c->length = length;
|
|
|
+ c->seq = 0;
|
|
|
+
|
|
|
+ memcpy((void *)c->payload, (void *)buf, length);
|
|
|
+ retval = RAND_pseudo_bytes((unsigned char *)(c->payload+length),CELL_PAYLOAD_SIZE-length);
|
|
|
+ if (retval == -1) /* RAND_pseudo_bytes() error */
|
|
|
+ {
|
|
|
+ free((void *)c);
|
|
|
+ return NULL;
|
|
|
+ } /* RAND_pseudo_bytes() error */
|
|
|
+
|
|
|
+ return c;
|
|
|
+ } /* valid parameters */
|
|
|
+ else /* invalid parameters */
|
|
|
+ return NULL;
|
|
|
+}
|
|
|
|
|
|
-#if 0 /* actually, the aci is 0 for padding cells */
|
|
|
- if(cell->aci == 0) {
|
|
|
- log(LOG_DEBUG,"check_sane_cell(): Cell has aci=0. Dropping.");
|
|
|
- return -1;
|
|
|
- }
|
|
|
-#endif
|
|
|
+int pack_create(uint16_t aci, unsigned char *onion, uint32_t onionlen, unsigned char **cellbuf, unsigned int *cellbuflen)
|
|
|
+{
|
|
|
+ cell_t *c;
|
|
|
+ unsigned char *buf;
|
|
|
+ unsigned int buflen;
|
|
|
+ unsigned int cells;
|
|
|
+ unsigned int dataleft;
|
|
|
+ unsigned int i;
|
|
|
+
|
|
|
+ assert(aci && onion && onionlen && cellbuf && cellbuflen);
|
|
|
|
|
|
-#if 0 /* actually, the length is sometimes encrypted. so it's ok. */
|
|
|
- if(cell->length > 120) {
|
|
|
- log(LOG_DEBUG,"check_sane_cell(): Cell claims to have payload length %d. Dropping.",cell->length);
|
|
|
+ /* copy the onion into a buffer, prepend with onion length */
|
|
|
+ buflen = onionlen+4;
|
|
|
+ buf = (unsigned char *)malloc(buflen);
|
|
|
+ if (!buf) /* malloc() error */
|
|
|
return -1;
|
|
|
+
|
|
|
+ log(LOG_DEBUG,"pack_create() : Setting onion length to %u.",onionlen);
|
|
|
+ *(uint32_t*)buf = htonl(onionlen);
|
|
|
+ memcpy((void *)(buf+4),(void *)onion,onionlen);
|
|
|
+
|
|
|
+ /* calculate number of cells required */
|
|
|
+ if (buflen%CELL_PAYLOAD_SIZE == 0)
|
|
|
+ cells = buflen/CELL_PAYLOAD_SIZE;
|
|
|
+ else
|
|
|
+ cells = buflen/CELL_PAYLOAD_SIZE+1;
|
|
|
+
|
|
|
+ /* allocate memory for the cells */
|
|
|
+ *cellbuflen = cells * sizeof(cell_t);
|
|
|
+ *cellbuf = malloc(*cellbuflen);
|
|
|
+ if (!*cellbuf) /* malloc() error */
|
|
|
+ return -1;
|
|
|
+
|
|
|
+ log(LOG_DEBUG,"pack_create() : Allocated memory for %u cells.",cells);
|
|
|
+
|
|
|
+ /* create cells one by one */
|
|
|
+ dataleft = buflen;
|
|
|
+ for(i=0; i<cells; i++)
|
|
|
+ {
|
|
|
+ log(LOG_DEBUG,"pack_create() : Packing %u bytes of data.",dataleft);
|
|
|
+ if (dataleft >= CELL_PAYLOAD_SIZE)
|
|
|
+ {
|
|
|
+ c = new_create_cell(aci,CELL_PAYLOAD_SIZE,buf+i*CELL_PAYLOAD_SIZE);
|
|
|
+ dataleft -= CELL_PAYLOAD_SIZE;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ c = new_create_cell(aci,dataleft,buf+i*CELL_PAYLOAD_SIZE);
|
|
|
+
|
|
|
+ if (!c) /* cell creation failed */
|
|
|
+ {
|
|
|
+ free((void *)*cellbuf);
|
|
|
+ return -1;
|
|
|
+ } /* cell creation failed */
|
|
|
+
|
|
|
+ log(LOG_DEBUG,"pack_create() : new_create_cell succeeded; copying the cell into output buffer");
|
|
|
+ /* cell has been created, now copy into buffer */
|
|
|
+ memcpy((void *)(*cellbuf+i*sizeof(cell_t)),(void *)c,sizeof(cell_t));
|
|
|
+ free((void *)c);
|
|
|
}
|
|
|
-#endif
|
|
|
-
|
|
|
- return 0; /* looks good */
|
|
|
+
|
|
|
+ free(buf);
|
|
|
+ return 0;
|
|
|
}
|
|
|
|