Commit 33ec5679 authored by Dafydd Harries's avatar Dafydd Harries
Browse files

add fake UDP socket implementation

darcs-hash:20070113154659-c9803-35893e1d1a40a64cea7a10bd6dc5001904ee5184.gz
parent e9a93d35
AM_CFLAGS = -Wall -Werror $(GLIB_CFLAGS)
libudp_a_SOURCES = udp.h udp.c udp-generic.c
libudp_a_SOURCES = udp.h udp.c udp-generic.c udp-fake.h udp-fake.c
noinst_LIBRARIES = libudp.a
......@@ -11,10 +11,14 @@ udp_client_LDADD = libudp.a $(GLIB_LIBS)
udp_echo_server_LDADD = libudp.a $(GLIB_LIBS)
check_PROGRAMS = test
test_LDADD = libudp.a $(GLIB_LIBS)
test-echo.sh::
chmod +x $(srcdir)/$@
EXTRA_DIST = test-echo.sh
TESTS = test-echo.sh
TESTS = test-echo.sh test
#!/bin/sh
set -e
./udp-echo-server &
server_pid=$!
# give server a chance to bind to socket
sleep 1
output=`echo foo | ./udp-client`
kill $server_pid
test "$output" = foo || exit 1
......
#include <string.h>
#include <arpa/inet.h>
#include <glib.h>
#include <udp.h>
#include <udp-fake.h>
int
main (void)
{
UDPSocketManager man;
UDPSocket sock;
struct sockaddr_in sin;
guint len;
gchar buf[1024];
udp_fake_socket_manager_init (&man);
/* create fake socket */
sin.sin_addr.s_addr = INADDR_ANY;
sin.sin_port = 0;
udp_socket_manager_alloc_socket (&man, &sock, &sin);
/* test recv */
strcpy (buf, "hello");
len = 5;
sin.sin_addr.s_addr = htonl (0x01020304);
sin.sin_port = htons (2345);
udp_fake_socket_manager_push_recv (&man, &sin, len, buf);
memset (buf, '\0', 5);
memset (&sin, '\0', sizeof (sin));
len = udp_socket_recv (&sock, &sin, sizeof (buf), buf);
g_assert (len == 5);
g_assert (strcmp (buf, "hello") == 0);
g_assert (ntohl (sin.sin_addr.s_addr) == 0x01020304);
g_assert (ntohs (sin.sin_port) == 2345);
/* test send */
strcpy (buf, "lala");
len = 4;
udp_socket_send (&sock, &sin, len, buf);
memset (buf, '\0', len);
memset (&sin, '\0', sizeof (sin));
len = udp_fake_socket_manager_pop_send (&man, &sin, sizeof (buf), buf);
g_assert (len == 4);
g_assert (strcmp (buf, "lala"));
g_assert (ntohl (sin.sin_addr.s_addr) == 0x01020304);
g_assert (ntohs (sin.sin_port) == 2345);
man.close (&man);
return 0;
}
#include <string.h>
#include <arpa/inet.h>
#include <glib.h>
#include <udp.h>
typedef struct _Packet Packet;
struct _Packet
{
struct sockaddr_in from;
struct sockaddr_in to;
guint len;
gchar buf[1024];
};
typedef struct _UDPFakeSocketManagerPriv UDPFakeSocketManagerPriv;
struct _UDPFakeSocketManagerPriv
{
GSList *recv_queue;
GSList *send_queue;
};
static void *
_g_slist_pop (GSList **list)
{
void *data;
GSList *head;
if (*list == NULL)
return NULL;
head = *list;
data = (*list)->data;
*list = (*list)->next;
g_slist_free_1 (head);
return data;
}
static gboolean
fake_send (
UDPSocket *sock,
struct sockaddr_in *to,
guint len,
gchar *buf)
{
Packet *packet;
UDPSocketManager *man;
UDPFakeSocketManagerPriv *priv;
packet = g_slice_new0 (Packet);
packet->len = len;
packet->to = *to;
strncpy (packet->buf, buf, len);
man = (UDPSocketManager *) sock->priv;
priv = (UDPFakeSocketManagerPriv *) man->priv;
priv->send_queue = g_slist_append (priv->send_queue, packet);
return TRUE;
}
static gint
fake_recv (
UDPSocket *sock,
struct sockaddr_in *from,
guint len,
gchar *buf)
{
Packet *packet;
UDPSocketManager *man;
UDPFakeSocketManagerPriv *priv;
man = (UDPSocketManager *) sock->priv;
priv = (UDPFakeSocketManagerPriv *) man->priv;
packet = (Packet *) _g_slist_pop (&priv->recv_queue);
if (packet == NULL)
{
g_debug ("recv queue underflow");
return 0;
}
len = packet->len;
memcpy (buf, packet->buf, len);
memcpy (from, &(packet->from), sizeof (*from));
g_slice_free (Packet, packet);
return len;
}
static gboolean
fake_socket_init (
UDPSocketManager *man,
UDPSocket *sock,
struct sockaddr_in *sin)
{
sock->send = fake_send;
sock->recv = fake_recv;
sock->priv = man;
return TRUE;
}
void
udp_fake_socket_manager_push_recv (
UDPSocketManager *man,
struct sockaddr_in *from,
guint len,
gchar *buf)
{
Packet *packet;
UDPFakeSocketManagerPriv *priv;
packet = g_slice_new0 (Packet);
packet->len = len;
packet->from = *from;
strncpy (packet->buf, buf, len);
priv = (UDPFakeSocketManagerPriv *) man->priv;
priv->recv_queue = g_slist_append (priv->recv_queue, packet);
}
guint
udp_fake_socket_manager_pop_send (
UDPSocketManager *man,
struct sockaddr_in *to,
guint len,
gchar *buf)
{
UDPFakeSocketManagerPriv *priv;
Packet *packet;
priv = (UDPFakeSocketManagerPriv *) man->priv;
packet = (Packet *) _g_slist_pop (&priv->send_queue);
if (!packet)
return 0;
*to = packet->to;
return packet->len;
}
static void
fake_socket_manager_close (UDPSocketManager *man)
{
g_slice_free (UDPFakeSocketManagerPriv, man->priv);
}
void
udp_fake_socket_manager_init (UDPSocketManager *man)
{
man->init = fake_socket_init;
man->select = NULL;
man->close = fake_socket_manager_close;
man->priv = g_slice_new0 (UDPFakeSocketManagerPriv);
}
void
udp_fake_socket_manager_init (UDPSocketManager *man);
void
udp_fake_socket_manager_push_recv (
UDPSocketManager *man,
struct sockaddr_in *from,
guint len,
gchar *buf);
guint
udp_fake_socket_manager_pop_send (
UDPSocketManager *man,
struct sockaddr_in *to,
guint len,
gchar *buf);
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment