Example #1
0
block_reader::pointer block_reader::get(std::istream & base, const setup::version & version) {
	
	USE_ENUM_NAMES(block_compression)
	
	uint32_t expected_checksum = load_number<uint32_t>(base);
	crypto::crc32 actual_checksum;
	actual_checksum.init();
	
	uint32_t stored_size;
	block_compression compression;
	
	if(version >= INNO_VERSION(4, 0, 9)) {
		
		stored_size = actual_checksum.load_number<uint32_t>(base);
		uint8_t compressed = actual_checksum.load_number<uint8_t>(base);
		
		compression = compressed ? (version >= INNO_VERSION(4, 1, 6) ? LZMA1 : Zlib) : Stored;
		
	} else {
		
		uint32_t compressed_size = actual_checksum.load_number<uint32_t>(base);
		uint32_t uncompressed_size = actual_checksum.load_number<uint32_t>(base);
		
		if(compressed_size == uint32_t(-1)) {
			stored_size = uncompressed_size, compression = Stored;
		} else {
			stored_size = compressed_size, compression = Zlib;
		}
		
		// Add the size of a CRC32 checksum for each 4KiB subblock.
		stored_size += uint32_t(ceildiv<uint64_t>(stored_size, 4096) * 4);
	}
	
	if(actual_checksum.finalize() != expected_checksum) {
		throw block_error("block CRC32 mismatch");
	}
	
	debug("[block] size: " << stored_size << "  compression: " << compression);
	
	boost::shared_ptr<io::filtering_istream> fis = boost::make_shared<io::filtering_istream>();
	
	switch(compression) {
		case Stored: break;
		case Zlib: fis->push(io::zlib_decompressor(), 8192); break;
	#if INNOEXTRACT_HAVE_LZMA
		case LZMA1: fis->push(inno_lzma1_decompressor(), 8192); break;
	#else
		case LZMA1: throw block_error("LZMA decompression not supported by this "
			                  + std::string(innoextract_name) + " build");
	#endif
	}
	
	fis->push(inno_block_filter(), 4096);
	
	fis->push(io::restrict(base, 0, stored_size));
	
	return fis;
}
Example #2
0
/**
	socket_send_to : 'socket -> buf:string -> pos:int -> length:int -> addr:{host:'int32,port:int} -> int
	<doc>
	Send data from an unconnected UDP socket to the given address.
	</doc>
**/
static value socket_send_to( value o, value data, value pos, value len, value vaddr ) {
	int p,l,dlen;
	value host, port;
	struct sockaddr_in addr;
	val_check_kind(o,k_socket);
	val_check(data,string);
	val_check(pos,int);
	val_check(len,int);
	val_check(vaddr,object);
	host = val_field(vaddr, f_host);
	port = val_field(vaddr, f_port);
	val_check(host,int32);
	val_check(port,int);
	p = val_int(pos);
	l = val_int(len);
	dlen = val_strlen(data);
	memset(&addr,0,sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_port = htons(val_int(port));
	*(int*)&addr.sin_addr.s_addr = val_int32(host);
	if( p < 0 || l < 0 || p > dlen || p + l > dlen )
		neko_error();
	POSIX_LABEL(send_again);
	dlen = sendto(val_sock(o), val_string(data) + p , l, MSG_NOSIGNAL, (struct sockaddr*)&addr, sizeof(addr));
	if( dlen == SOCKET_ERROR ) {
		HANDLE_EINTR(send_again);
		return block_error();
	}
	return alloc_int(dlen);
}
Example #3
0
/**
	socket_send_to : 'socket -> buf:string -> pos:int -> length:int -> addr:{host:'int32,port:int} -> int
	<doc>
	Send data from an unconnected UDP socket to the given address.
	</doc>
**/
static value socket_send_to( value o, value dataBuf, value pos, value len, value vaddr ) {
	int p,l;
	value host, port;
	struct sockaddr_in addr;
	val_check_kind(o,k_socket);
   buffer buf = val_to_buffer(dataBuf);
	const char *cdata = buffer_data(buf);
	int dlen = buffer_size(buf);
	val_check(pos,int);
	val_check(len,int);
	val_check(vaddr,object);
	host = val_field(vaddr, f_host);
	port = val_field(vaddr, f_port);
	val_check(host,int);
	val_check(port,int);
	p = val_int(pos);
	l = val_int(len);
	memset(&addr,0,sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_port = htons(val_int(port));
	*(int*)&addr.sin_addr.s_addr = val_int(host);
	if( p < 0 || l < 0 || p > dlen || p + l > dlen )
		neko_error();

   SOCKET sock = val_sock(o);
	gc_enter_blocking();
	POSIX_LABEL(send_again);
	dlen = sendto(sock, cdata + p , l, MSG_NOSIGNAL, (struct sockaddr*)&addr, sizeof(addr));
	if( dlen == SOCKET_ERROR ) {
		HANDLE_EINTR(send_again);
		return block_error();
	}
	gc_exit_blocking();
	return alloc_int(dlen);
}
Example #4
0
static value socket_recv_from( value o, value dataBuf, value pos, value len, value addr ) {
	int p,l,ret;
	int retry = 0;
	struct sockaddr_in saddr;
	SockLen slen = sizeof(saddr);
	val_check_kind(o,k_socket);
	val_check(dataBuf,buffer);
	buffer buf = val_to_buffer(dataBuf);
   char *data = buffer_data(buf);
   int dlen = buffer_size(buf);
	val_check(pos,int);
	val_check(len,int);
	val_check(addr,object);
	p = val_int(pos);
	l = val_int(len);

	if( p < 0 || l < 0 || p > dlen || p + l > dlen )
		neko_error();
   SOCKET sock = val_sock(o);
   gc_enter_blocking();
	POSIX_LABEL(recv_from_again);
	if( retry++ > NRETRYS ) {
      ret = recv(sock,data+p,l,MSG_NOSIGNAL);
	} else
		ret = recvfrom(sock, data + p , l, MSG_NOSIGNAL, (struct sockaddr*)&saddr, &slen);
	if( ret == SOCKET_ERROR ) {
		HANDLE_EINTR(recv_from_again);
		return block_error();
	}
   gc_exit_blocking();
	alloc_field(addr,f_host,alloc_int32(*(int*)&saddr.sin_addr));
	alloc_field(addr,f_port,alloc_int(ntohs(saddr.sin_port)));
	return alloc_int(ret);
}
Example #5
0
/**
	socket_recv : 'socket -> buf:string -> pos:int -> len:int -> int
	<doc>Read up to [len] bytes from [buf] starting at [pos] from a connected socket.
	Return the number of bytes readed.</doc>
**/
static value socket_recv( value o, value data, value pos, value len ) {
	int p,l,dlen,ret;
	int retry = 0;
	val_check_kind(o,k_socket);
	val_check(data,string);
	val_check(pos,int);
	val_check(len,int);
	p = val_int(pos);
	l = val_int(len);
	dlen = val_strlen(data);
	if( p < 0 || l < 0 || p > dlen || p + l > dlen )
		neko_error();
	POSIX_LABEL(recv_again);
	if( retry++ > NRETRYS ) {
		sock_tmp t;
		t.sock = val_sock(o);
		t.buf = val_string(data) + p;
		t.size = l;
		neko_thread_blocking(tmp_recv,&t);
		ret = t.ret;
	} else
		ret = recv(val_sock(o), val_string(data) + p , l, MSG_NOSIGNAL);
	if( ret == SOCKET_ERROR ) {
		HANDLE_EINTR(recv_again);
		return block_error();
	}
	return alloc_int(ret);
}
Example #6
0
HL_PRIM int hl_socket_send_char( hl_socket *s, int c ) {
	char cc;
	cc = (char)(unsigned char)c;
	if( !s )
		return -2;
	if( send(s->sock,&cc,1,MSG_NOSIGNAL) == SOCKET_ERROR )
		return block_error();
	return 1;
}
Example #7
0
HL_PRIM int hl_socket_send( hl_socket *s, vbyte *buf, int pos, int len ) {
	int r;
	if( !s )
		return -2;
	r = send(s->sock, (char*)buf + pos, len, MSG_NOSIGNAL);
	if( r == SOCKET_ERROR )
		return block_error();
	return len;
}
Example #8
0
HL_PRIM int hl_socket_recv( hl_socket *s, vbyte *buf, int pos, int len ) {
	int	ret;
	if( !s )
		return -2;
	hl_blocking(true);
	ret = recv(s->sock, (char*)buf + pos, len, MSG_NOSIGNAL);
	hl_blocking(false);
	if( ret == SOCKET_ERROR )
		return block_error();
	return ret;
}
Example #9
0
HL_PRIM int hl_socket_send_to( hl_socket *s, char *data, int len, int host, int port ) {
	struct sockaddr_in addr;
	if( !s ) return -2;
	memset(&addr,0,sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_port = htons((unsigned short)port);
	*(int*)&addr.sin_addr.s_addr = host;
	len = sendto(s->sock, data, len, MSG_NOSIGNAL, (struct sockaddr*)&addr, sizeof(addr));
	if( len == SOCKET_ERROR )
		return block_error();
	return len;
}
Example #10
0
static value ssl_handshake( value ssl ) {
	int r;
	val_check_kind(ssl,k_ssl);
	POSIX_LABEL(handshake_again);
	r = mbedtls_ssl_handshake( val_ssl(ssl) );
	if( r == SOCKET_ERROR ) {
		HANDLE_EINTR(handshake_again);
		return block_error();
	}else if( r != 0 )
		return ssl_error(r);
	return val_true;
}
Example #11
0
static value socket_accept( value o ) {
	SOCKET sock = val_sock(o);
	struct sockaddr_in addr;
	SockLen addrlen = sizeof(addr);
	SOCKET s;
	gc_enter_blocking();
	s = accept(sock,(struct sockaddr*)&addr,&addrlen);
	if( s == INVALID_SOCKET )
		return block_error();
	gc_exit_blocking();
	return alloc_abstract(k_socket,(void *)(socket_int)s);
}
Example #12
0
HL_PRIM int hl_socket_recv_char( hl_socket *s ) {
	char cc;
	int ret;
	if( !s ) return -2;
	hl_blocking(true);
	ret = recv(s->sock,&cc,1,MSG_NOSIGNAL);
	hl_blocking(false);
	if( ret == SOCKET_ERROR )
		return block_error();
	if( ret == 0 )
		return -2;
	return (unsigned char)cc;
}
Example #13
0
/**
	socket_accept : 'socket -> 'socket
	<doc>Accept an incoming connection request</doc>
**/
static value socket_accept( value o ) {
	struct sockaddr_in addr;
	unsigned int addrlen = sizeof(addr);
	SOCKET s;
	val_check_kind(o,k_socket);
	POSIX_LABEL(accept_again);
	s = accept(val_sock(o),(struct sockaddr*)&addr,&addrlen);
	if( s == INVALID_SOCKET ) {
		HANDLE_EINTR(accept_again);
		return block_error();
	}
	return alloc_abstract(k_socket,(value)(int_val)s);
}
Example #14
0
/**
	socket_connect : 'socket -> host:'int32 -> port:int -> void
	<doc>Connect the socket the given [host] and [port]</doc>
**/
static value socket_connect( value o, value host, value port ) {
	struct sockaddr_in addr;
	val_check_kind(o,k_socket);
	val_check(host,int32);
	val_check(port,int);
	memset(&addr,0,sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_port = htons(val_int(port));
	*(int*)&addr.sin_addr.s_addr = val_int32(host);
	if( connect(val_sock(o),(struct sockaddr*)&addr,sizeof(addr)) != 0 )
		return block_error();
	return val_true;
}
Example #15
0
/**
	socket_send_char : 'socket -> int -> void
	<doc>Send a character over a connected socket. Must be in the range 0..255</doc>
**/
static value socket_send_char( value o, value v ) {
	int c;
	unsigned char cc;
	val_check_kind(o,k_socket);
	val_check(v,int);
	c = val_int(v);
	if( c < 0 || c > 255 )
		neko_error();
	cc = (unsigned char)c;
	POSIX_LABEL(send_char_again);
	if( send(val_sock(o),&cc,1,MSG_NOSIGNAL) == SOCKET_ERROR ) {
		HANDLE_EINTR(send_char_again);
		return block_error();
	}
	return val_true;
}
Example #16
0
/**
	socket_recv_char : 'socket -> int
	<doc>Read a single char from a connected socket.</doc>
**/
static value socket_recv_char( value o ) {
	int ret;
	unsigned char cc;
	SOCKET sock = val_sock(o);
	gc_enter_blocking();
	POSIX_LABEL(recv_char_again);
	ret = recv(sock,(char *)&cc,1,MSG_NOSIGNAL);
	if( ret == SOCKET_ERROR ) {
		HANDLE_EINTR(recv_char_again);
		return block_error();
	}
	gc_exit_blocking();
	if( ret == 0 )
		val_throw(alloc_string("Connection closed"));
	return alloc_int(cc);
}
Example #17
0
HL_PRIM bool hl_socket_connect( hl_socket *s, int host, int port ) {
	struct sockaddr_in addr;
	memset(&addr,0,sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_port = htons((unsigned short)port);
	*(int*)&addr.sin_addr.s_addr = host;
	if( !s ) return false;
	hl_blocking(true);
	if( connect(s->sock,(struct sockaddr*)&addr,sizeof(addr)) != 0 ) {
		int err = block_error();
		hl_blocking(false);
		if( err == -1 ) return true; // in progress
		return false;
	}
	hl_blocking(false);
	return true;
}
Example #18
0
/**
	socket_send_char : 'socket -> int -> void
	<doc>Send a character over a connected socket. Must be in the range 0..255</doc>
**/
static value socket_send_char( value o, value v ) {
	int c;
	unsigned char cc;
        SOCKET sock = val_sock(o);
	val_check(v,int);
	c = val_int(v);
	if( c < 0 || c > 255 )
		return alloc_null();
	cc = (unsigned char)c;
	gc_enter_blocking();
	POSIX_LABEL(send_char_again);
	if( send(sock,(const char *)&cc,1,MSG_NOSIGNAL) == SOCKET_ERROR ) {
		HANDLE_EINTR(send_char_again);
		return block_error();
	}
	gc_exit_blocking();
	return alloc_bool(true);
}
Example #19
0
HL_PRIM int hl_socket_recv_from( hl_socket *s, char *data, int len, int *host, int *port ) {
	struct sockaddr_in saddr;
	socklen_t slen = sizeof(saddr);
	if( !s ) return -2;
	hl_blocking(true);
	len = recvfrom(s->sock, data, len, MSG_NOSIGNAL, (struct sockaddr*)&saddr, &slen);
	hl_blocking(false);
	if( len == SOCKET_ERROR ) {
#ifdef	HL_WIN
		if( WSAGetLastError() == WSAECONNRESET )
			len = 0;
		else
#endif
		return block_error();
	}
	*host = *(int*)&saddr.sin_addr;
	*port = ntohs(saddr.sin_port);
	return len;
}
Example #20
0
/**
	socket_send : 'socket -> buf:string -> pos:int -> len:int -> int
	<doc>Send up to [len] bytes from [buf] starting at [pos] over a connected socket.
	Return the number of bytes sent.</doc>
**/
static value socket_send( value o, value data, value pos, value len ) {
	int p,l,dlen;
	val_check_kind(o,k_socket);
	val_check(data,string);
	val_check(pos,int);
	val_check(len,int);
	p = val_int(pos);
	l = val_int(len);
	dlen = val_strlen(data);
	if( p < 0 || l < 0 || p > dlen || p + l > dlen )
		neko_error();
	POSIX_LABEL(send_again);
	dlen = send(val_sock(o), val_string(data) + p , l, MSG_NOSIGNAL);
	if( dlen == SOCKET_ERROR ) {
		HANDLE_EINTR(send_again);
		return block_error();
	}
	return alloc_int(dlen);
}
Example #21
0
/**
	socket_write : 'socket -> string -> void
	<doc>Send the whole content of a string over a connected socket.</doc>
**/
static value socket_write( value o, value data ) {
	const char *cdata;
	int datalen, slen;
	val_check_kind(o,k_socket);
	val_check(data,string);
	cdata = val_string(data);
	datalen = val_strlen(data);
	while( datalen > 0 ) {
		POSIX_LABEL(write_again);
		slen = send(val_sock(o),cdata,datalen,MSG_NOSIGNAL);
		if( slen == SOCKET_ERROR ) {
			HANDLE_EINTR(write_again);
			return block_error();
		}
		cdata += slen;
		datalen -= slen;
	}
	return val_true;
}
Example #22
0
/**
	socket_read : 'socket -> string
	<doc>Read the whole content of a the data available from a socket until the connection close.
	If the socket hasn't been close by the other side, the function might block.
	</doc>
**/
static value socket_read( value o ) {
	buffer b;
	char buf[256];
	int len;
	val_check_kind(o,k_socket);
	b = alloc_buffer(NULL);
	while( true ) {
		POSIX_LABEL(read_again);
		len = recv(val_sock(o),buf,256,MSG_NOSIGNAL);
		if( len == SOCKET_ERROR ) {
			HANDLE_EINTR(read_again);
			return block_error();
		}
		if( len == 0 )
			break;
		buffer_append_sub(b,buf,len);
	}
	return buffer_to_string(b);
}
Example #23
0
/**
	socket_connect : 'socket -> host:'string -> port:int -> void
	<doc>Connect the socket the given [host] and [port]</doc>
**/
static value socket_connect( value o, value host, value port ) {
    val_check(host,string);
    val_check(port,int);

    struct sockaddr* addr;
    struct sockaddr_in addr4;
    struct sockaddr_in6 addr6;
    unsigned char ip[16];
    int len = 0;

    if (inet_pton(AF_INET, val_string(host), ip) == 1) {

         memset(&addr4,0,sizeof(addr4));
         addr4.sin_family = AF_INET;
         addr4.sin_port = htons(val_int(port));
         *(int*)&addr4.sin_addr.s_addr = *(int*)ip;
         addr = (struct sockaddr*)&addr4;
         len = sizeof (struct sockaddr_in);
    }
    else if (inet_pton(AF_INET6, val_string(host), ip) == 1) {

         memset(&addr6,0,sizeof(addr6));
         addr6.sin6_family = AF_INET6;
         addr6.sin6_port = htons(val_int(port));
         memcpy(addr6.sin6_addr.s6_addr, ip, 16);
         addr = (struct sockaddr*)&addr6;
         len = sizeof (struct sockaddr_in6);
    }

	gc_enter_blocking();
	if( connect(val_sock(o),addr,len) != 0 )
	{
		// This will throw a "Blocking" exception if the "error" was because
		// it's a non-blocking socket with connection in progress, otherwise
		// it will do nothing.
		(void) block_error();
		// If the previous line did not throw an exception, then it was a real
		// connect failure.
		val_throw(alloc_string("std@socket_connect"));
	}
	gc_exit_blocking();
	return alloc_bool(true);
}
Example #24
0
static value ssl_send( value ssl, value data, value pos, value len ) {
	int p,l,dlen;
	val_check_kind(ssl,k_ssl);
	val_check(data,string);
	val_check(pos,int);
	val_check(len,int);
	p = val_int(pos);
	l = val_int(len);
	dlen = val_strlen(data);
	if( p < 0 || l < 0 || p > dlen || p + l > dlen )
		neko_error();
	POSIX_LABEL(send_again);
	dlen = mbedtls_ssl_write( val_ssl(ssl), (const unsigned char *)val_string(data) + p, l );
	if( dlen == SOCKET_ERROR ) {
		HANDLE_EINTR(send_again);
		return block_error();
	}
	return alloc_int(dlen);
}
Example #25
0
static value ssl_recv( value ssl, value data, value pos, value len ) {
	int p,l,dlen;
	void * buf;
	val_check_kind(ssl,k_ssl);
	val_check(data,string);
	val_check(pos,int);
	val_check(len,int);
	p = val_int( pos );
	l = val_int( len );
	buf = (void *) (val_string(data) + p);
	POSIX_LABEL(recv_again);
	dlen = mbedtls_ssl_read( val_ssl(ssl), buf, l );
	if( dlen == SOCKET_ERROR ) {
		HANDLE_EINTR(recv_again);
		return block_error();
	}
	if( dlen < 0 )
		neko_error();
	return alloc_int( dlen );
}
Example #26
0
/**
	socket_send : 'socket -> buf:string -> pos:int -> len:int -> int
	<doc>Send up to [len] bytes from [buf] starting at [pos] over a connected socket.
	Return the number of bytes sent.</doc>
**/
static value socket_send( value o, value data, value pos, value len ) {
	int p,l,dlen;
	SOCKET sock = val_sock(o);
	val_check(pos,int);
	val_check(len,int);
        buffer buf = val_to_buffer(data);
        if (!buf)
           hx_failure("not bytebuffer");
	p = val_int(pos);
	l = val_int(len);
	dlen = buffer_size(buf);
	if( p < 0 || l < 0 || p > dlen || p + l > dlen )
		return alloc_null();
	gc_enter_blocking();
	dlen = send(sock, buffer_data(buf) + p , l, MSG_NOSIGNAL);
	if( dlen == SOCKET_ERROR )
		return block_error();
	gc_exit_blocking();
	return alloc_int(dlen);
}
Example #27
0
static  value ssl_read( value ssl ) {
	int len, bufsize = 256;
	buffer b;
	unsigned char buf[256];
	mbedtls_ssl_context *ctx;
	val_check_kind(ssl,k_ssl);
	ctx = val_ssl(ssl);
	b = alloc_buffer(NULL);
	while( true ) {
		POSIX_LABEL(read_again);
		len = mbedtls_ssl_read( ctx, buf, bufsize );
		if( len == SOCKET_ERROR ) {
			HANDLE_EINTR(read_again);
			return block_error();
		}
		if( len == 0 )
			break;
		buffer_append_sub(b,(const char *)buf,len);
	}
	return buffer_to_string(b);
}
Example #28
0
static value ssl_write( value ssl, value data ) {
	int len, slen;
	const unsigned char *s;
	mbedtls_ssl_context *ctx;
	val_check_kind(ssl,k_ssl);
	val_check(data,string);
	s = (const unsigned char *)val_string( data );
	len = val_strlen( data );
	ctx = val_ssl(ssl);
	while( len > 0 ) {
		POSIX_LABEL( write_again );
		slen = mbedtls_ssl_write( ctx, s, len );
		if( slen == SOCKET_ERROR ) {
			HANDLE_EINTR( write_again );
			return block_error();
		}
		s += slen;
		len -= slen;
	}
	return val_true;
}
Example #29
0
/**
	socket_write : 'socket -> string -> void
	<doc>Send the whole content of a string over a connected socket.</doc>
**/
static value socket_write( value o, value data ) {
	const char *cdata;
	int datalen, slen;
	SOCKET sock = val_sock(o);
	val_check(data,buffer);
	buffer buf = val_to_buffer(data);
	cdata = buffer_data(buf);
	datalen = buffer_size(buf);
	gc_enter_blocking();
	while( datalen > 0 ) {
		POSIX_LABEL(write_again);
		slen = send(sock,cdata,datalen,MSG_NOSIGNAL);
		if( slen == SOCKET_ERROR ) {
			HANDLE_EINTR(write_again);
			return block_error();
		}
		cdata += slen;
		datalen -= slen;
	}
	gc_exit_blocking();
	return alloc_bool(true);
}
Example #30
0
/**
	socket_connect : 'socket -> host:'int32 -> port:int -> void
	<doc>Connect the socket the given [host] and [port]</doc>
**/
static value socket_connect( value o, value host, value port ) {
	struct sockaddr_in addr;
	val_check(host,int);
	val_check(port,int);
	memset(&addr,0,sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_port = htons(val_int(port));
	*(int*)&addr.sin_addr.s_addr = val_int(host);
	gc_enter_blocking();
	if( connect(val_sock(o),(struct sockaddr*)&addr,sizeof(addr)) != 0 )
	{
		// This will throw a "Blocking" exception if the "error" was because
		// it's a non-blocking socket with connection in progress, otherwise
		// it will do nothing.
		(void) block_error();
		// If the previous line did not throw an exception, then it was a real
		// connect failure.
		val_throw(alloc_string("std@socket_connect"));
	}
	gc_exit_blocking();
	return alloc_bool(true);
}