2017-07-13 10:28:42 +03:00
/*
CTDB protocol marshalling
Copyright ( C ) Amitay Isaacs 2015 - 2017
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation ; either version 3 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program ; if not , see < http : //www.gnu.org/licenses/>.
*/
# include "replace.h"
# include "system/network.h"
# include <talloc.h>
# include <tdb.h>
# include "protocol.h"
# include "protocol_private.h"
/*
* Basic data types
*/
2017-06-29 15:24:20 +03:00
size_t ctdb_uint8_len ( uint8_t * in )
{
return sizeof ( uint8_t ) ;
}
void ctdb_uint8_push ( uint8_t * in , uint8_t * buf , size_t * npush )
{
* buf = * in ;
* npush = sizeof ( uint8_t ) ;
}
int ctdb_uint8_pull ( uint8_t * buf , size_t buflen , uint8_t * out , size_t * npull )
{
if ( buflen < sizeof ( uint8_t ) ) {
return EMSGSIZE ;
}
* out = * buf ;
* npull = sizeof ( uint8_t ) ;
return 0 ;
}
2017-07-12 11:38:00 +03:00
size_t ctdb_uint16_len ( uint16_t * in )
{
return sizeof ( uint16_t ) ;
}
void ctdb_uint16_push ( uint16_t * in , uint8_t * buf , size_t * npush )
{
memcpy ( buf , in , sizeof ( uint16_t ) ) ;
* npush = sizeof ( uint16_t ) ;
}
int ctdb_uint16_pull ( uint8_t * buf , size_t buflen , uint16_t * out , size_t * npull )
{
if ( buflen < sizeof ( uint16_t ) ) {
return EMSGSIZE ;
}
memcpy ( out , buf , sizeof ( uint16_t ) ) ;
* npull = sizeof ( uint16_t ) ;
return 0 ;
}
2017-06-29 15:09:26 +03:00
size_t ctdb_int32_len ( int32_t * in )
2017-07-13 10:28:42 +03:00
{
return sizeof ( int32_t ) ;
}
2017-06-29 15:09:26 +03:00
void ctdb_int32_push ( int32_t * in , uint8_t * buf , size_t * npush )
2017-07-13 10:28:42 +03:00
{
2017-06-29 15:09:26 +03:00
memcpy ( buf , in , sizeof ( int32_t ) ) ;
* npush = sizeof ( int32_t ) ;
2017-07-13 10:28:42 +03:00
}
2017-06-29 15:09:26 +03:00
int ctdb_int32_pull ( uint8_t * buf , size_t buflen , int32_t * out , size_t * npull )
2017-07-13 10:28:42 +03:00
{
if ( buflen < sizeof ( int32_t ) ) {
return EMSGSIZE ;
}
2017-06-29 15:09:26 +03:00
memcpy ( out , buf , sizeof ( int32_t ) ) ;
* npull = sizeof ( int32_t ) ;
2017-07-13 10:28:42 +03:00
return 0 ;
}
2017-06-29 15:14:23 +03:00
size_t ctdb_uint32_len ( uint32_t * in )
2017-07-13 10:28:42 +03:00
{
return sizeof ( uint32_t ) ;
}
2017-06-29 15:14:23 +03:00
void ctdb_uint32_push ( uint32_t * in , uint8_t * buf , size_t * npush )
2017-07-13 10:28:42 +03:00
{
2017-06-29 15:14:23 +03:00
memcpy ( buf , in , sizeof ( uint32_t ) ) ;
* npush = sizeof ( uint32_t ) ;
2017-07-13 10:28:42 +03:00
}
2017-06-29 15:14:23 +03:00
int ctdb_uint32_pull ( uint8_t * buf , size_t buflen , uint32_t * out , size_t * npull )
2017-07-13 10:28:42 +03:00
{
if ( buflen < sizeof ( uint32_t ) ) {
return EMSGSIZE ;
}
2017-06-29 15:14:23 +03:00
memcpy ( out , buf , sizeof ( uint32_t ) ) ;
* npull = sizeof ( uint32_t ) ;
2017-07-13 10:28:42 +03:00
return 0 ;
}
2017-06-29 15:15:43 +03:00
size_t ctdb_uint64_len ( uint64_t * in )
2017-07-13 10:28:42 +03:00
{
return sizeof ( uint64_t ) ;
}
2017-06-29 15:15:43 +03:00
void ctdb_uint64_push ( uint64_t * in , uint8_t * buf , size_t * npush )
2017-07-13 10:28:42 +03:00
{
2017-06-29 15:15:43 +03:00
memcpy ( buf , in , sizeof ( uint64_t ) ) ;
* npush = sizeof ( uint64_t ) ;
2017-07-13 10:28:42 +03:00
}
2017-06-29 15:15:43 +03:00
int ctdb_uint64_pull ( uint8_t * buf , size_t buflen , uint64_t * out , size_t * npull )
2017-07-13 10:28:42 +03:00
{
if ( buflen < sizeof ( uint64_t ) ) {
return EMSGSIZE ;
}
2017-06-29 15:15:43 +03:00
memcpy ( out , buf , sizeof ( uint64_t ) ) ;
* npull = sizeof ( uint64_t ) ;
2017-07-13 10:28:42 +03:00
return 0 ;
}
2017-06-29 15:16:56 +03:00
size_t ctdb_double_len ( double * in )
2017-07-13 10:28:42 +03:00
{
return sizeof ( double ) ;
}
2017-06-29 15:16:56 +03:00
void ctdb_double_push ( double * in , uint8_t * buf , size_t * npush )
2017-07-13 10:28:42 +03:00
{
2017-06-29 15:16:56 +03:00
memcpy ( buf , in , sizeof ( double ) ) ;
* npush = sizeof ( double ) ;
2017-07-13 10:28:42 +03:00
}
2017-06-29 15:16:56 +03:00
int ctdb_double_pull ( uint8_t * buf , size_t buflen , double * out , size_t * npull )
2017-07-13 10:28:42 +03:00
{
if ( buflen < sizeof ( double ) ) {
return EMSGSIZE ;
}
2017-06-29 15:16:56 +03:00
memcpy ( out , buf , sizeof ( double ) ) ;
* npull = sizeof ( double ) ;
2017-07-13 10:28:42 +03:00
return 0 ;
}
2017-06-29 17:11:45 +03:00
size_t ctdb_bool_len ( bool * in )
{
uint8_t u8 = * in ;
return ctdb_uint8_len ( & u8 ) ;
}
void ctdb_bool_push ( bool * in , uint8_t * buf , size_t * npush )
{
size_t np ;
uint8_t u8 = * in ;
ctdb_uint8_push ( & u8 , buf , & np ) ;
* npush = np ;
}
int ctdb_bool_pull ( uint8_t * buf , size_t buflen , bool * out , size_t * npull )
{
size_t np ;
uint8_t u8 ;
int ret ;
ret = ctdb_uint8_pull ( buf , buflen , & u8 , & np ) ;
if ( ret ! = 0 ) {
return ret ;
}
if ( u8 = = 0 ) {
* out = false ;
} else if ( u8 = = 1 ) {
* out = true ;
} else {
return EINVAL ;
}
* npull = np ;
return 0 ;
}
2017-07-06 11:05:04 +03:00
size_t ctdb_chararray_len ( char * in , size_t len )
{
return len ;
}
void ctdb_chararray_push ( char * in , size_t len , uint8_t * buf , size_t * npush )
{
memcpy ( buf , in , len ) ;
* npush = len ;
}
int ctdb_chararray_pull ( uint8_t * buf , size_t buflen , char * out , size_t len ,
size_t * npull )
{
if ( buflen < len ) {
return EMSGSIZE ;
}
memcpy ( out , buf , len ) ;
out [ len - 1 ] = ' \0 ' ;
* npull = len ;
return 0 ;
}
2017-06-29 11:48:51 +03:00
size_t ctdb_string_len ( const char * * in )
2017-07-13 10:28:42 +03:00
{
2017-06-29 11:48:51 +03:00
if ( * in = = NULL ) {
2017-07-13 10:28:42 +03:00
return 0 ;
}
2017-06-29 11:48:51 +03:00
return strlen ( * in ) + 1 ;
2017-07-13 10:28:42 +03:00
}
2017-06-29 11:48:51 +03:00
void ctdb_string_push ( const char * * in , uint8_t * buf , size_t * npush )
2017-07-13 10:28:42 +03:00
{
2017-06-29 11:48:51 +03:00
size_t len ;
len = ctdb_string_len ( in ) ;
if ( len > 0 ) {
memcpy ( buf , * in , len ) ;
2017-07-13 10:28:42 +03:00
}
2017-06-29 11:48:51 +03:00
* npush = len ;
2017-07-13 10:28:42 +03:00
}
int ctdb_string_pull ( uint8_t * buf , size_t buflen , TALLOC_CTX * mem_ctx ,
2017-06-29 11:48:51 +03:00
const char * * out , size_t * npull )
2017-07-13 10:28:42 +03:00
{
2017-06-29 11:48:51 +03:00
const char * str ;
if ( buflen > UINT32_MAX ) {
return EMSGSIZE ;
}
2017-07-13 10:28:42 +03:00
if ( buflen = = 0 ) {
* out = NULL ;
2017-06-29 11:48:51 +03:00
* npull = 0 ;
2017-07-13 10:28:42 +03:00
return 0 ;
}
str = talloc_strndup ( mem_ctx , ( char * ) buf , buflen ) ;
if ( str = = NULL ) {
return ENOMEM ;
}
* out = str ;
2017-06-29 11:48:51 +03:00
* npull = ctdb_string_len ( & str ) ;
2017-07-13 10:28:42 +03:00
return 0 ;
}
2017-04-20 05:45:24 +03:00
size_t ctdb_stringn_len ( const char * * in )
2017-07-13 10:28:42 +03:00
{
2017-04-20 05:45:24 +03:00
uint32_t u32 = ctdb_string_len ( in ) ;
return ctdb_uint32_len ( & u32 ) + u32 ;
2017-07-13 10:28:42 +03:00
}
2017-04-20 05:45:24 +03:00
void ctdb_stringn_push ( const char * * in , uint8_t * buf , size_t * npush )
2017-07-13 10:28:42 +03:00
{
2017-04-20 05:45:24 +03:00
size_t offset = 0 , np ;
uint32_t u32 = ctdb_string_len ( in ) ;
2017-07-13 10:28:42 +03:00
2017-04-20 05:45:24 +03:00
ctdb_uint32_push ( & u32 , buf + offset , & np ) ;
offset + = np ;
ctdb_string_push ( in , buf + offset , & np ) ;
offset + = np ;
* npush = offset ;
2017-07-13 10:28:42 +03:00
}
int ctdb_stringn_pull ( uint8_t * buf , size_t buflen , TALLOC_CTX * mem_ctx ,
2017-04-20 05:45:24 +03:00
const char * * out , size_t * npull )
2017-07-13 10:28:42 +03:00
{
2017-04-20 05:45:24 +03:00
size_t offset = 0 , np ;
uint32_t u32 ;
int ret ;
2017-07-13 10:28:42 +03:00
2017-04-20 05:45:24 +03:00
ret = ctdb_uint32_pull ( buf + offset , buflen - offset , & u32 , & np ) ;
if ( ret ! = 0 ) {
return ret ;
2017-07-13 10:28:42 +03:00
}
2017-04-20 05:45:24 +03:00
offset + = np ;
2017-07-13 10:28:42 +03:00
2017-04-20 05:45:24 +03:00
if ( buflen - offset < u32 ) {
return EMSGSIZE ;
2017-07-13 10:28:42 +03:00
}
2017-04-20 05:45:24 +03:00
ret = ctdb_string_pull ( buf + offset , u32 , mem_ctx , out , & np ) ;
if ( ret ! = 0 ) {
return ret ;
2017-07-13 10:28:42 +03:00
}
2017-04-20 05:45:24 +03:00
offset + = np ;
2017-07-13 10:28:42 +03:00
2017-04-20 05:45:24 +03:00
* npull = offset ;
2017-07-13 10:28:42 +03:00
return 0 ;
}
/*
* System defined data types
*/
2017-06-29 15:18:27 +03:00
size_t ctdb_pid_len ( pid_t * in )
2017-07-13 10:28:42 +03:00
{
return sizeof ( pid_t ) ;
}
2017-06-29 15:18:27 +03:00
void ctdb_pid_push ( pid_t * in , uint8_t * buf , size_t * npush )
2017-07-13 10:28:42 +03:00
{
2017-06-29 15:18:27 +03:00
memcpy ( buf , in , sizeof ( pid_t ) ) ;
* npush = sizeof ( pid_t ) ;
2017-07-13 10:28:42 +03:00
}
2017-06-29 15:18:27 +03:00
int ctdb_pid_pull ( uint8_t * buf , size_t buflen , pid_t * out , size_t * npull )
2017-07-13 10:28:42 +03:00
{
if ( buflen < sizeof ( pid_t ) ) {
return EMSGSIZE ;
}
2017-06-29 15:18:27 +03:00
memcpy ( out , buf , sizeof ( pid_t ) ) ;
* npull = sizeof ( pid_t ) ;
2017-07-13 10:28:42 +03:00
return 0 ;
}
2017-07-06 07:48:38 +03:00
size_t ctdb_timeval_len ( struct timeval * in )
{
return sizeof ( struct timeval ) ;
}
void ctdb_timeval_push ( struct timeval * in , uint8_t * buf , size_t * npush )
{
memcpy ( buf , in , sizeof ( struct timeval ) ) ;
* npush = sizeof ( struct timeval ) ;
}
int ctdb_timeval_pull ( uint8_t * buf , size_t buflen , struct timeval * out ,
size_t * npull )
{
if ( buflen < sizeof ( struct timeval ) ) {
return EMSGSIZE ;
}
memcpy ( out , buf , sizeof ( struct timeval ) ) ;
* npull = sizeof ( struct timeval ) ;
return 0 ;
}
2017-07-06 10:52:25 +03:00
/*
* Dummy type to tackle structure padding
*/
size_t ctdb_padding_len ( int count )
{
return count % SIZEOF_VOID_P ;
}
void ctdb_padding_push ( int count , uint8_t * buf , size_t * npush )
{
uint8_t padding [ count ] ;
size_t aligned_count = count % SIZEOF_VOID_P ;
if ( aligned_count > 0 ) {
memset ( padding , 0 , aligned_count ) ;
memcpy ( buf , padding , aligned_count ) ;
}
* npush = aligned_count ;
}
int ctdb_padding_pull ( uint8_t * buf , size_t buflen , int count , size_t * npull )
{
size_t aligned_count = count % SIZEOF_VOID_P ;
if ( buflen < aligned_count ) {
return EMSGSIZE ;
}
* npull = aligned_count ;
return 0 ;
}