2010-04-02 07:30:06 -07:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
# include <config.h>
|
2010-07-30 18:54:48 -07:00
|
|
|
#endif /* ifdef HAVE_CONFIG_H */
|
2010-04-02 07:30:06 -07:00
|
|
|
|
2010-04-02 22:29:44 -07:00
|
|
|
#ifdef HAVE_ALLOCA_H
|
|
|
|
# include <alloca.h>
|
|
|
|
#elif defined __GNUC__
|
|
|
|
# define alloca __builtin_alloca
|
|
|
|
#elif defined _AIX
|
|
|
|
# define alloca __alloca
|
|
|
|
#elif defined _MSC_VER
|
|
|
|
# include <malloc.h>
|
|
|
|
# define alloca _alloca
|
2010-07-30 18:54:48 -07:00
|
|
|
#else /* ifdef HAVE_ALLOCA_H */
|
2010-04-02 22:29:44 -07:00
|
|
|
# include <stddef.h>
|
|
|
|
# ifdef __cplusplus
|
|
|
|
extern "C"
|
2010-07-30 18:54:48 -07:00
|
|
|
# endif /* ifdef __cplusplus */
|
2011-10-20 22:40:01 -07:00
|
|
|
void *alloca(size_t);
|
2010-07-30 18:54:48 -07:00
|
|
|
#endif /* ifdef HAVE_ALLOCA_H */
|
2010-04-02 07:30:06 -07:00
|
|
|
|
|
|
|
#include <string.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
|
|
#ifdef HAVE_NETINET_IN_H
|
|
|
|
# include <netinet/in.h>
|
2010-07-30 18:54:48 -07:00
|
|
|
#endif /* ifdef HAVE_NETINET_IN_H */
|
2010-04-02 07:30:06 -07:00
|
|
|
|
2010-04-02 22:29:44 -07:00
|
|
|
#ifdef _WIN32
|
2010-04-02 07:30:06 -07:00
|
|
|
# include <winsock2.h>
|
2010-07-30 18:54:48 -07:00
|
|
|
#endif /* ifdef _WIN32 */
|
2010-04-02 22:29:44 -07:00
|
|
|
|
2010-04-02 07:30:06 -07:00
|
|
|
#include <Eina.h>
|
|
|
|
|
|
|
|
#include "Eet.h"
|
|
|
|
#include "Eet_private.h"
|
|
|
|
|
|
|
|
#define MAGIC_EET_DATA_PACKET 0x4270ACE1
|
|
|
|
|
|
|
|
struct _Eet_Connection
|
|
|
|
{
|
2010-07-31 11:57:35 -07:00
|
|
|
Eet_Read_Cb *eet_read_cb;
|
2010-07-31 11:54:54 -07:00
|
|
|
Eet_Write_Cb *eet_write_cb;
|
2010-07-31 11:57:35 -07:00
|
|
|
void *user_data;
|
2010-04-02 07:30:06 -07:00
|
|
|
|
2010-07-31 11:54:54 -07:00
|
|
|
size_t allocated;
|
|
|
|
size_t size;
|
|
|
|
size_t received;
|
2010-04-02 07:30:06 -07:00
|
|
|
|
2010-07-31 11:57:35 -07:00
|
|
|
void *buffer;
|
2010-04-02 07:30:06 -07:00
|
|
|
};
|
|
|
|
|
2010-06-27 05:10:46 -07:00
|
|
|
EAPI Eet_Connection *
|
2010-07-31 11:57:35 -07:00
|
|
|
eet_connection_new(Eet_Read_Cb *eet_read_cb,
|
2010-07-31 11:54:54 -07:00
|
|
|
Eet_Write_Cb *eet_write_cb,
|
2010-07-31 11:57:35 -07:00
|
|
|
const void *user_data)
|
2010-04-02 07:30:06 -07:00
|
|
|
{
|
2010-07-31 11:54:54 -07:00
|
|
|
Eet_Connection *conn;
|
2010-04-02 07:30:06 -07:00
|
|
|
|
|
|
|
if (!eet_read_cb || !eet_write_cb)
|
2011-10-20 22:40:01 -07:00
|
|
|
return NULL;
|
2010-04-02 07:30:06 -07:00
|
|
|
|
|
|
|
conn = calloc(1, sizeof (Eet_Connection));
|
|
|
|
if (!conn)
|
2011-10-20 22:40:01 -07:00
|
|
|
return NULL;
|
2010-04-02 07:30:06 -07:00
|
|
|
|
|
|
|
conn->eet_read_cb = eet_read_cb;
|
|
|
|
conn->eet_write_cb = eet_write_cb;
|
2010-07-27 18:45:57 -07:00
|
|
|
conn->user_data = (void *)user_data;
|
2010-04-02 07:30:06 -07:00
|
|
|
|
|
|
|
return conn;
|
2011-12-02 06:42:13 -08:00
|
|
|
}
|
2010-04-02 07:30:06 -07:00
|
|
|
|
2010-06-27 05:10:46 -07:00
|
|
|
EAPI int
|
2010-07-31 11:54:54 -07:00
|
|
|
eet_connection_received(Eet_Connection *conn,
|
2010-07-31 11:57:35 -07:00
|
|
|
const void *data,
|
2010-07-31 11:54:54 -07:00
|
|
|
size_t size)
|
2010-04-02 07:30:06 -07:00
|
|
|
{
|
2010-07-30 18:54:48 -07:00
|
|
|
if ((!conn) || (!data) || (!size))
|
2011-10-20 22:40:01 -07:00
|
|
|
return size;
|
2010-04-02 07:30:06 -07:00
|
|
|
|
|
|
|
do {
|
2010-07-27 18:45:57 -07:00
|
|
|
size_t copy_size;
|
|
|
|
|
|
|
|
if (conn->size == 0)
|
|
|
|
{
|
2010-08-02 07:30:46 -07:00
|
|
|
const int *msg;
|
2010-07-27 18:45:57 -07:00
|
|
|
size_t packet_size;
|
|
|
|
|
2010-08-02 07:30:46 -07:00
|
|
|
if (size < sizeof (int) * 2)
|
2011-10-20 22:40:01 -07:00
|
|
|
break;
|
2010-07-27 18:45:57 -07:00
|
|
|
|
|
|
|
msg = data;
|
|
|
|
/* Check the magic */
|
2010-08-02 07:30:46 -07:00
|
|
|
if (ntohl(msg[0]) != MAGIC_EET_DATA_PACKET)
|
2011-10-20 22:40:01 -07:00
|
|
|
break;
|
2010-07-27 18:45:57 -07:00
|
|
|
|
2010-08-02 07:30:46 -07:00
|
|
|
packet_size = ntohl(msg[1]);
|
2010-07-27 18:45:57 -07:00
|
|
|
/* Message should always be under 64K */
|
|
|
|
if (packet_size > 64 * 1024)
|
2011-10-20 22:40:01 -07:00
|
|
|
break;
|
2010-07-27 18:45:57 -07:00
|
|
|
|
2010-08-02 07:30:46 -07:00
|
|
|
data = (void *)(msg + 2);
|
|
|
|
size -= sizeof (int) * 2;
|
2010-07-27 18:45:57 -07:00
|
|
|
if ((size_t)packet_size <= size)
|
|
|
|
{
|
2011-10-20 22:40:01 -07:00
|
|
|
/* Not a partial receive, go the quick way. */
|
|
|
|
if (!conn->eet_read_cb(data, packet_size, conn->user_data))
|
2010-07-27 18:45:57 -07:00
|
|
|
break;
|
|
|
|
|
2011-10-20 22:40:01 -07:00
|
|
|
data = (void *)((char *)data + packet_size);
|
|
|
|
size -= packet_size;
|
2010-07-27 18:45:57 -07:00
|
|
|
|
2011-10-20 22:40:01 -07:00
|
|
|
conn->received = 0;
|
|
|
|
continue;
|
2010-07-27 18:45:57 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
conn->size = packet_size;
|
|
|
|
if (conn->allocated < conn->size)
|
|
|
|
{
|
2010-07-31 11:54:54 -07:00
|
|
|
void *tmp;
|
2010-07-27 18:45:57 -07:00
|
|
|
|
|
|
|
tmp = realloc(conn->buffer, conn->size);
|
|
|
|
if (!tmp)
|
2011-10-20 22:40:01 -07:00
|
|
|
break;
|
2010-07-27 18:45:57 -07:00
|
|
|
|
|
|
|
conn->buffer = tmp;
|
|
|
|
conn->allocated = conn->size;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Partial receive */
|
|
|
|
copy_size =
|
2011-10-20 22:40:01 -07:00
|
|
|
(conn->size - conn->received >=
|
|
|
|
size) ? size : conn->size - conn->received;
|
2010-07-27 18:45:57 -07:00
|
|
|
memcpy((char *)conn->buffer + conn->received, data, copy_size);
|
|
|
|
|
|
|
|
conn->received += copy_size;
|
|
|
|
data = (void *)((char *)data + copy_size);
|
|
|
|
size -= copy_size;
|
|
|
|
|
|
|
|
if (conn->received == conn->size)
|
|
|
|
{
|
|
|
|
size_t data_size;
|
|
|
|
|
|
|
|
data_size = conn->size;
|
|
|
|
conn->size = 0;
|
|
|
|
conn->received = 0;
|
|
|
|
|
|
|
|
/* Completed a packet. */
|
|
|
|
if (!conn->eet_read_cb(conn->buffer, data_size, conn->user_data))
|
|
|
|
{
|
2011-10-20 22:40:01 -07:00
|
|
|
/* Something goes wrong. Stop now. */
|
|
|
|
size += data_size;
|
|
|
|
break;
|
2010-07-27 18:45:57 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} while (size > 0);
|
2010-04-02 07:30:06 -07:00
|
|
|
|
|
|
|
return size;
|
2011-12-02 06:42:13 -08:00
|
|
|
}
|
2010-04-02 07:30:06 -07:00
|
|
|
|
|
|
|
static Eina_Bool
|
2010-07-31 11:54:54 -07:00
|
|
|
_eet_connection_raw_send(Eet_Connection *conn,
|
2010-07-31 11:57:35 -07:00
|
|
|
void *data,
|
2010-07-31 11:54:54 -07:00
|
|
|
int data_size)
|
2010-04-02 07:30:06 -07:00
|
|
|
{
|
2010-08-02 07:30:46 -07:00
|
|
|
int *message;
|
2010-04-02 07:30:06 -07:00
|
|
|
|
|
|
|
/* Message should never be above 64K */
|
|
|
|
if (data_size > 64 * 1024)
|
2011-10-20 22:40:01 -07:00
|
|
|
return EINA_FALSE;
|
2010-04-02 07:30:06 -07:00
|
|
|
|
2010-08-02 07:30:46 -07:00
|
|
|
message = alloca(data_size + sizeof (int) * 2);
|
|
|
|
message[0] = htonl(MAGIC_EET_DATA_PACKET);
|
|
|
|
message[1] = htonl(data_size);
|
2010-04-02 07:30:06 -07:00
|
|
|
|
2010-08-02 07:30:46 -07:00
|
|
|
memcpy(message + 2, data, data_size);
|
2010-04-02 07:30:06 -07:00
|
|
|
|
2010-07-27 18:45:57 -07:00
|
|
|
conn->eet_write_cb(message,
|
2010-08-02 07:30:46 -07:00
|
|
|
data_size + sizeof (int) * 2,
|
2010-07-27 18:45:57 -07:00
|
|
|
conn->user_data);
|
2010-04-02 07:30:06 -07:00
|
|
|
return EINA_TRUE;
|
2011-12-02 06:42:13 -08:00
|
|
|
}
|
2010-04-02 07:30:06 -07:00
|
|
|
|
2010-06-27 05:10:46 -07:00
|
|
|
EAPI Eina_Bool
|
2010-07-31 11:57:35 -07:00
|
|
|
eet_connection_send(Eet_Connection *conn,
|
2010-07-31 11:54:54 -07:00
|
|
|
Eet_Data_Descriptor *edd,
|
2010-07-31 11:57:35 -07:00
|
|
|
const void *data_in,
|
|
|
|
const char *cipher_key)
|
2010-04-02 07:30:06 -07:00
|
|
|
{
|
2010-07-31 11:54:54 -07:00
|
|
|
void *flat_data;
|
2010-04-02 07:30:06 -07:00
|
|
|
int data_size;
|
|
|
|
Eina_Bool ret = EINA_FALSE;
|
|
|
|
|
2010-07-27 18:45:57 -07:00
|
|
|
flat_data = eet_data_descriptor_encode_cipher(edd,
|
|
|
|
data_in,
|
|
|
|
cipher_key,
|
|
|
|
&data_size);
|
2010-04-02 07:30:06 -07:00
|
|
|
if (!flat_data)
|
2011-10-20 22:40:01 -07:00
|
|
|
return EINA_FALSE;
|
2010-04-02 07:30:06 -07:00
|
|
|
|
|
|
|
if (_eet_connection_raw_send(conn, flat_data, data_size))
|
2011-10-20 22:40:01 -07:00
|
|
|
ret = EINA_TRUE;
|
2010-04-02 07:30:06 -07:00
|
|
|
|
|
|
|
free(flat_data);
|
|
|
|
return ret;
|
2011-12-02 06:42:13 -08:00
|
|
|
}
|
2010-04-02 07:30:06 -07:00
|
|
|
|
2010-06-27 05:10:46 -07:00
|
|
|
EAPI Eina_Bool
|
2010-07-31 11:54:54 -07:00
|
|
|
eet_connection_node_send(Eet_Connection *conn,
|
2010-07-31 11:57:35 -07:00
|
|
|
Eet_Node *node,
|
|
|
|
const char *cipher_key)
|
2010-04-02 07:30:06 -07:00
|
|
|
{
|
2010-07-31 11:54:54 -07:00
|
|
|
void *data;
|
2010-04-02 07:30:06 -07:00
|
|
|
int data_size;
|
|
|
|
Eina_Bool ret = EINA_FALSE;
|
|
|
|
|
|
|
|
data = eet_data_node_encode_cipher(node, cipher_key, &data_size);
|
|
|
|
if (!data)
|
2011-10-20 22:40:01 -07:00
|
|
|
return EINA_FALSE;
|
2010-04-02 07:30:06 -07:00
|
|
|
|
|
|
|
if (_eet_connection_raw_send(conn, data, data_size))
|
2011-10-20 22:40:01 -07:00
|
|
|
ret = EINA_TRUE;
|
2010-04-02 07:30:06 -07:00
|
|
|
|
|
|
|
free(data);
|
|
|
|
return ret;
|
2011-12-02 06:42:13 -08:00
|
|
|
}
|
2010-04-02 07:30:06 -07:00
|
|
|
|
2010-06-27 05:10:46 -07:00
|
|
|
EAPI void *
|
2010-07-31 11:54:54 -07:00
|
|
|
eet_connection_close(Eet_Connection *conn,
|
2010-07-31 11:57:35 -07:00
|
|
|
Eina_Bool *on_going)
|
2010-04-02 07:30:06 -07:00
|
|
|
{
|
2010-07-31 11:54:54 -07:00
|
|
|
void *user_data;
|
2010-04-02 07:30:06 -07:00
|
|
|
|
|
|
|
if (!conn)
|
2011-10-20 22:40:01 -07:00
|
|
|
return NULL;
|
2010-04-02 07:30:06 -07:00
|
|
|
|
|
|
|
if (on_going)
|
2011-10-20 22:40:01 -07:00
|
|
|
*on_going = conn->received == 0 ? EINA_FALSE : EINA_TRUE;
|
2010-04-02 07:30:06 -07:00
|
|
|
|
|
|
|
user_data = conn->user_data;
|
|
|
|
|
|
|
|
free(conn->buffer);
|
|
|
|
free(conn);
|
|
|
|
|
|
|
|
return user_data;
|
2011-12-02 06:42:13 -08:00
|
|
|
}
|
2010-07-30 18:54:48 -07:00
|
|
|
|