You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

232 lines
7.0 KiB

/******************************************************************************
* Copyright © 2014-2016 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
#include "OS_portable.h"
#include "../includes/curve25519.h"
// threadsafe
int32_t iguana_rwnum(int32_t rwflag,uint8_t *serialized,int32_t len,void *endianedp)
{
int32_t i; uint64_t x;
if ( rwflag == 0 )
{
x = 0;
for (i=len-1; i>=0; i--)
{
x <<= 8;
x |= serialized[i];
}
switch ( len )
{
case 1: *(uint8_t *)endianedp = (uint8_t)x; break;
case 2: *(uint16_t *)endianedp = (uint16_t)x; break;
case 4: *(uint32_t *)endianedp = (uint32_t)x; break;
case 8: *(uint64_t *)endianedp = (uint64_t)x; break;
}
}
else
{
x = 0;
switch ( len )
{
case 1: x = *(uint8_t *)endianedp; break;
case 2: x = *(uint16_t *)endianedp; break;
case 4: x = *(uint32_t *)endianedp; break;
case 8: x = *(uint64_t *)endianedp; break;
}
for (i=0; i<len; i++,x >>= 8)
serialized[i] = (uint8_t)(x & 0xff);
}
return(len);
}
int32_t iguana_validatehdr(char *symbol,struct iguana_msghdr *H)
{
int32_t i = 0,len = -1;
if ( strcmp(symbol,"VPN") != 0 )
{
for (i=0; Iguana_validcommands[i]!=0&&Iguana_validcommands[i][0]!=0; i++)
if ( strcmp(H->command,Iguana_validcommands[i]) == 0 )
break;
}
if ( Iguana_validcommands[i][0] != 0 )
{
iguana_rwnum(0,H->serdatalen,sizeof(H->serdatalen),(uint32_t *)&len);
if ( len > IGUANA_MAXPACKETSIZE )
return(-1);
}
return(len);
}
int32_t iguana_rwbignum(int32_t rwflag,uint8_t *serialized,int32_t len,uint8_t *endianedp)
{
int32_t i;
if ( rwflag == 0 )
{
for (i=0; i<len; i++)
endianedp[i] = serialized[len - 1 - i];
}
else
{
for (i=0; i<len; i++)
serialized[i] = endianedp[len - 1 - i];
}
return(len);
}
int32_t iguana_sethdr(struct iguana_msghdr *H,const uint8_t netmagic[4],char *command,uint8_t *data,int32_t datalen)
{
bits256 hash2,tmp; int32_t i;
memset(H,0,sizeof(*H));
memcpy(H->netmagic,netmagic,4);
strncpy(H->command,command,12);
iguana_rwnum(1,H->serdatalen,sizeof(int32_t),&datalen);
if ( data != 0 && datalen != 0 )
{
hash2 = bits256_doublesha256(0,data,datalen);
iguana_rwbignum(1,tmp.bytes,sizeof(tmp),hash2.bytes);
for (i=0; i<4; i++)
H->hash[i] = tmp.bytes[i];
}
else H->hash[0] = 0x5d, H->hash[1] = 0xf6, H->hash[2] = 0xe0, H->hash[3] = 0xe2;
return(datalen + sizeof(*H));
}
uint8_t *iguana_varint16(int32_t rwflag,uint8_t *serialized,uint16_t *varint16p)
{
uint16_t n = 0;
if ( rwflag == 0 )
{
n = *serialized++;
n |= ((int32_t)*serialized++ << 8);
*varint16p = n;
}
else
{
n = *varint16p;
*serialized++ = (uint8_t)n & 0xff;
*serialized++ = (uint8_t)(n >> 8) & 0xff;
}
return(serialized);
}
uint8_t *iguana_varint32(int32_t rwflag,uint8_t *serialized,uint16_t *varint16p)
{
serialized = iguana_varint16(rwflag,serialized,varint16p);
serialized = iguana_varint16(rwflag,serialized,&varint16p[1]);
return(serialized);
}
uint8_t *iguana_varint64(int32_t rwflag,uint8_t *serialized,uint32_t *varint32p)
{
serialized = iguana_varint32(rwflag,serialized,(uint16_t *)varint32p);
serialized = iguana_varint32(rwflag,serialized,(uint16_t *)&varint32p[1]);
return(serialized);
}
int32_t iguana_rwvarint(int32_t rwflag,uint8_t *serialized,uint64_t *varint64p)
{
uint64_t n; int32_t vlen = 1;
if ( rwflag == 0 )
{
*varint64p = 0;
if ( (n= *serialized++) >= 0xfd )
{
if ( n == 0xfd )
{
n = 0;
iguana_varint16(rwflag,serialized,(uint16_t *)&n);
vlen += 2;
}
else if ( n == 0xfe )
{
n = 0;
iguana_varint32(rwflag,serialized,(uint16_t *)&n);
vlen += 4;
}
else if ( n == 0xff )
{
n = 0;
iguana_varint64(rwflag,serialized,(uint32_t *)&n);
vlen += 8;
}
}
*varint64p = n;
}
else
{
n = *varint64p;
if ( n < 0xfd )
*serialized++ = (uint8_t)n;
else if ( n >= 0xfd && n <= 0xffff )
{
*serialized++ = 0xfd;
iguana_varint16(rwflag,serialized,(uint16_t *)varint64p);
vlen += 2;
}
else if ( n > 0xffff && n <= 0xffffffff )
{
*serialized++ = 0xfe;
iguana_varint32(rwflag,serialized,(uint16_t *)varint64p);
vlen += 4;
}
else if ( n > 0xffffffff )
{
*serialized++ = 0xff;
iguana_varint64(rwflag,serialized,(uint32_t *)varint64p);
vlen += 8;
}
}
return(vlen);
}
int32_t iguana_rwvarint32(int32_t rwflag,uint8_t *serialized,uint32_t *int32p)
{
int32_t len; uint64_t x = 0;
if ( rwflag != 0 )
x = *int32p;
len = iguana_rwvarint(rwflag,serialized,&x);
if ( rwflag == 0 )
*int32p = (int32_t)x;
return(len);
}
int32_t iguana_rwstr(int32_t rwflag,uint8_t *serialized,int32_t maxlen,char *endianedp)
{
int32_t vlen; uint64_t n;
if ( rwflag == 0 )
{
vlen = iguana_rwvarint(rwflag,serialized,&n);
memcpy(endianedp,&serialized[vlen],n);
((uint8_t *)endianedp)[n] = 0;
}
else
{
n = strlen(endianedp);
if ( n > maxlen )
n = maxlen;
vlen = iguana_rwvarint(rwflag,serialized,&n);
memcpy(&serialized[vlen],endianedp,n);
}
return((int32_t)(n + vlen));
}
int32_t iguana_rwmem(int32_t rwflag,uint8_t *serialized,int32_t len,void *endianedp)
{
if ( rwflag == 0 )
memcpy(endianedp,serialized,len);
else memcpy(serialized,endianedp,len);
return(len);
}