#include <pjlib.h>
#include "test.h"
#if INCLUDE_SOCK_TEST
#define UDP_PORT 51234
#define TCP_PORT (UDP_PORT+10)
#define BIG_DATA_LEN 8192
#define ADDRESS "127.0.0.1"
static char bigdata[BIG_DATA_LEN];
static char bigbuffer[BIG_DATA_LEN];
#if defined(PJ_SOCKADDR_HAS_LEN) && PJ_SOCKADDR_HAS_LEN!=0
# define CHECK_SA_ZERO_LEN(addr, ret) \
if (((pj_addr_hdr*)(addr))->sa_zero_len != 0) \
return ret
#else
# define CHECK_SA_ZERO_LEN(addr, ret)
#endif
static int format_test(void)
{
unsigned char *p;
pj_in_addr addr;
char zero[64];
const unsigned char A[] = {127, 0, 0, 1};
PJ_LOG(3,(
"test",
"...format_test()"));
return -10;
p = (unsigned char*)&addr;
if (p[0]!=A[0] || p[1]!=A[1] || p[2]!=A[2] || p[3]!=A[3]) {
PJ_LOG(3,(
"test",
" error: mismatched address. p0=%d, p1=%d, " "p2=%d, p3=%d", p[0] & 0xFF, p[1] & 0xFF,
p[2] & 0xFF, p[3] & 0xFF));
return -15;
}
if (!p)
return -20;
return -22;
#if defined(PJ_HAS_IPV6) && PJ_HAS_IPV6!=0
{
pj_in_addr ipv4;
pj_in6_addr ipv6;
return -24;
p = (unsigned char*)&ipv4;
if (p[0]!=A[0] || p[1]!=A[1] || p[2]!=A[2] || p[3]!=A[3]) {
return -25;
}
return -26;
p = (unsigned char*)&ipv6;
if (p[0] != 0xfe || p[1] != 0x80 || p[2] != 0 || p[3] != 0 ||
p[4] != 0 || p[5] != 0 || p[6] != 0 || p[7] != 0 ||
p[8] != 0x02 || p[9] != 0xff || p[10] != 0x83 || p[11] != 0xff ||
p[12]!=0xfe || p[13]!=0x7c || p[14] != 0x8b || p[15]!=0x42)
{
return -27;
}
return -28;
return -29;
return -30;
return -31;
}
#endif
return -35;
if (!hostname || !hostname->
ptr || !hostname->
slen)
return -40;
PJ_LOG(3,(
"test",
"....hostname is %.*s",
(
int)hostname->
slen, hostname->
ptr));
#if !defined(PJ_SYMBIAN) || PJ_SYMBIAN==0
#endif
return 0;
}
static int parse_test(void)
{
#define IPv4 1
#define IPv6 2
struct test_t {
const char *input;
int result_af;
const char *result_ip;
};
struct test_t valid_tests[] =
{
{ "10.0.0.1:80", IPv4, "10.0.0.1", 80},
{ "10.0.0.1", IPv4, "10.0.0.1", 0},
{ "10.0.0.1:", IPv4, "10.0.0.1", 0},
{ "10.0.0.1:0", IPv4, "10.0.0.1", 0},
{ ":80", IPv4, "0.0.0.0", 80},
{ ":", IPv4, "0.0.0.0", 0},
#if !PJ_SYMBIAN
{ "localhost", IPv4, "127.0.0.1", 0},
{ "localhost:", IPv4, "127.0.0.1", 0},
{ "localhost:80", IPv4, "127.0.0.1", 80},
#endif
#if defined(PJ_HAS_IPV6) && PJ_HAS_IPV6
{ "fe::01:80", IPv6, "fe::01:80", 0},
{ "[fe::01]:80", IPv6, "fe::01", 80},
{ "fe::01", IPv6, "fe::01", 0},
{ "[fe::01]", IPv6, "fe::01", 0},
{ "fe::01:", IPv6, "fe::01", 0},
{ "[fe::01]:", IPv6, "fe::01", 0},
{ "::", IPv6, "::0", 0},
{ "[::]", IPv6, "::", 0},
{ ":::", IPv6, "::", 0},
{ "[::]:", IPv6, "::", 0},
{ ":::80", IPv6, "::", 80},
{ "[::]:80", IPv6, "::", 80},
#endif
};
struct test_t invalid_tests[] =
{
{ "10.0.0.1:abcd", IPv4},
{ "10.0.0.1:-1", IPv4},
{ "10.0.0.1:123456", IPv4},
{ "10:0:80", IPv4},
#if defined(PJ_HAS_IPV6) && PJ_HAS_IPV6
{ "[fe::01]:abcd", IPv6},
{ "[fe::01]:-1", IPv6},
{ "[fe::01]:123456", IPv6},
{ "fe::01:02::03:04:80", IPv6},
{ "[fe::01:02::03:04]:80", IPv6},
{ "[fe:01", IPv6},
#endif
};
unsigned i;
PJ_LOG(3,(
"test",
"...IP address parsing"));
switch (valid_tests[i].result_af) {
case IPv4:
break;
case IPv6:
break;
default:
continue;
}
pj_cstr(&input, valid_tests[i].input),
&addr);
PJ_LOG(1,(
"test",
".... failed when parsing %s (i=%d)",
valid_tests[i].input, i));
return -10;
}
CHECK_SA_ZERO_LEN(&addr, -20);
&result,
pj_cstr(&input, valid_tests[i].result_ip),
valid_tests[i].result_port);
PJ_LOG(1,(
"test",
".... error building IP address %s",
valid_tests[i].input));
return -30;
}
PJ_LOG(1,(
"test",
".... parsed result mismatched for %s",
valid_tests[i].input));
return -40;
}
pj_cstr(&input, valid_tests[i].input),
&addr);
PJ_LOG(1,(
"test",
".... failed when parsing %s",
valid_tests[i].input));
return -50;
}
CHECK_SA_ZERO_LEN(&addr, -55);
PJ_LOG(1,(
"test",
".... parsed result mismatched for %s",
valid_tests[i].input));
return -60;
}
}
switch (invalid_tests[i].result_af) {
case IPv4:
break;
case IPv6:
break;
default:
continue;
}
pj_cstr(&input, invalid_tests[i].input),
&addr);
PJ_LOG(1,(
"test",
".... expecting failure when parsing %s",
invalid_tests[i].input));
return -100;
}
}
return 0;
}
static int purity_test(void)
{
PJ_LOG(3,(
"test",
"...purity_test()"));
#if defined(PJ_SOCKADDR_HAS_LEN) && PJ_SOCKADDR_HAS_LEN!=0
{
unsigned cnt;
while (cnt--)
CHECK_SA_ZERO_LEN(&addr[cnt], -10);
}
CHECK_SA_ZERO_LEN(&addr[0], -20);
CHECK_SA_ZERO_LEN(&addr[0], -30);
CHECK_SA_ZERO_LEN(&addr[0], -40);
CHECK_SA_ZERO_LEN(&addr[0], -50);
while (cnt--)
CHECK_SA_ZERO_LEN(&ai[cnt].ai_addr, -60);
}
while (cnt--)
CHECK_SA_ZERO_LEN(&ai[cnt].ai_addr, -70);
}
}
#endif
return 0;
}
static int simple_sock_test(void)
{
int types[2];
int i;
PJ_LOG(3,(
"test",
"...simple_sock_test()"));
for (i=0; i<(
int)(
sizeof(types)/
sizeof(types[0])); ++i) {
app_perror("...error: unable to create socket", rc);
break;
} else {
if (rc != 0) {
app_perror("...error: close socket", rc);
break;
}
}
}
return rc;
}
static int send_recv_test(int sock_type,
int addrlen)
{
enum { DATA_LEN = 16 };
char senddata[DATA_LEN+4], recvdata[DATA_LEN+4];
TRACE_(("test", "....create_random_string()"));
senddata[DATA_LEN-1] = '\0';
TRACE_(("test", "....sendto()"));
if (dstaddr) {
sent = DATA_LEN;
app_perror("...sendto error", rc);
rc = -140; goto on_error;
}
} else {
sent = DATA_LEN;
app_perror("...send error", rc);
rc = -145; goto on_error;
}
}
TRACE_(("test", "....recv()"));
if (srcaddr) {
int srclen = sizeof(addr);
received = DATA_LEN;
app_perror("...recvfrom error", rc);
rc = -150; goto on_error;
}
if (srclen != addrlen)
return -151;
char srcaddr_str[32], addr_str[32];
PJ_LOG(3,(
"test",
"...error: src address mismatch (original=%s, " "recvfrom addr=%s)",
srcaddr_str, addr_str));
return -152;
}
} else {
total_received = 0;
do {
received = DATA_LEN-total_received;
rc =
pj_sock_recv(ss, recvdata+total_received, &received, 0);
app_perror("...recv error", rc);
rc = -155; goto on_error;
}
if (received <= 0) {
PJ_LOG(3,(
"",
"...error: socket has closed! (received=%d)",
received));
rc = -156; goto on_error;
}
if (received != DATA_LEN-total_received) {
PJ_LOG(3,(
"",
"...error: expecting %u bytes, got %u bytes",
DATA_LEN-total_received, received));
rc = -157; goto on_error;
}
}
total_received += received;
} while (total_received < DATA_LEN);
}
TRACE_(("test", "....memcmp()"));
if (
pj_memcmp(senddata, recvdata, DATA_LEN) != 0) {
PJ_LOG(3,(
"",
"...error: received data mismatch " "(got:'%s' expecting:'%s'",
recvdata, senddata));
rc = -160; goto on_error;
}
TRACE_(("test", "....sendto()"));
if (dstaddr) {
sent = BIG_DATA_LEN;
app_perror("...sendto error", rc);
rc = -161; goto on_error;
}
} else {
sent = BIG_DATA_LEN;
app_perror("...send error", rc);
rc = -165; goto on_error;
}
}
TRACE_(("test", "....recv()"));
total_received = 0;
do {
received = BIG_DATA_LEN-total_received;
rc =
pj_sock_recv(ss, bigbuffer+total_received, &received, 0);
app_perror("...recv error", rc);
rc = -170; goto on_error;
}
if (received <= 0) {
PJ_LOG(3,(
"",
"...error: socket has closed! (received=%d)",
received));
rc = -173; goto on_error;
}
if (received != BIG_DATA_LEN-total_received) {
PJ_LOG(3,(
"",
"...error: expecting %u bytes, got %u bytes",
BIG_DATA_LEN-total_received, received));
rc = -176; goto on_error;
}
}
total_received += received;
} while (total_received < BIG_DATA_LEN);
TRACE_(("test", "....memcmp()"));
if (
pj_memcmp(bigdata, bigbuffer, BIG_DATA_LEN) != 0) {
PJ_LOG(3,(
"",
"...error: received data has been altered!"));
rc = -180; goto on_error;
}
rc = 0;
on_error:
return rc;
}
static int udp_test(void)
{
PJ_LOG(3,(
"test",
"...udp_test()"));
if (rc != 0) {
app_perror("...error: unable to create socket", rc);
return -100;
}
if (rc != 0)
return -110;
if ((rc=
pj_sock_bind(ss, &dstaddr,
sizeof(dstaddr))) != 0) {
app_perror("...bind error udp:"ADDRESS, rc);
rc = -120; goto on_error;
}
if ((rc=
pj_sock_bind(cs, &srcaddr,
sizeof(srcaddr))) != 0) {
app_perror("...bind error", rc);
rc = -121; goto on_error;
}
sizeof(dstaddr));
if (rc != 0)
goto on_error;
&srcaddr, sizeof(dstaddr));
if (rc != 0)
goto on_error;
#if !defined(PJ_SYMBIAN) || PJ_SYMBIAN==0
if (rc != 0) {
app_perror("...connect() error", rc);
rc = -122; goto on_error;
}
if (rc != 0)
goto on_error;
sizeof(srcaddr));
if (rc != 0)
goto on_error;
#endif
on_error:
retval = rc;
app_perror("...error in closing socket", rc);
return -1000;
}
}
app_perror("...error in closing socket", rc);
return -1010;
}
}
return retval;
}
static int tcp_test(void)
{
PJ_LOG(3,(
"test",
"...tcp_test()"));
app_perror("...error: app_socketpair():", rc);
return -2000;
}
app_perror("...error in closing socket", rc);
return -2000;
}
app_perror("...error in closing socket", rc);
return -2010;
}
return retval;
}
static int ioctl_test(void)
{
return 0;
}
static int gethostbyname_test(void)
{
PJ_LOG(3,(
"test",
"...gethostbyname_test()"));
host =
pj_str(
"an-invalid-host-name");
return -20100;
else
return 0;
}
#if 0
#include "../pj/os_symbian.h"
static int connect_test()
{
RSocketServ rSockServ;
RSocket rSock;
TInetAddr inetAddr;
TRequestStatus reqStatus;
char buffer[16];
TPtrC8 data((const TUint8*)buffer, (TInt)sizeof(buffer));
int rc;
rc = rSockServ.Connect();
if (rc != KErrNone)
return rc;
rc = rSock.Open(rSockServ, KAfInet, KSockDatagram, KProtocolInetUdp);
if (rc != KErrNone)
{
rSockServ.Close();
return rc;
}
inetAddr.Init(KAfInet);
inetAddr.Input(_L("127.0.0.1"));
inetAddr.SetPort(80);
rSock.Connect(inetAddr, reqStatus);
User::WaitForRequest(reqStatus);
if (reqStatus != KErrNone) {
rSock.Close();
rSockServ.Close();
return rc;
}
rSock.Send(data, 0, reqStatus);
User::WaitForRequest(reqStatus);
if (reqStatus!=KErrNone) {
rSock.Close();
rSockServ.Close();
return rc;
}
rSock.Close();
rSockServ.Close();
return KErrNone;
}
#endif
int sock_test()
{
int rc;
#if 0
rc = connect_test();
if (rc != 0)
return rc;
#endif
rc = format_test();
if (rc != 0)
return rc;
rc = parse_test();
if (rc != 0)
return rc;
rc = purity_test();
if (rc != 0)
return rc;
rc = gethostbyname_test();
if (rc != 0)
return rc;
rc = simple_sock_test();
if (rc != 0)
return rc;
rc = ioctl_test();
if (rc != 0)
return rc;
rc = udp_test();
if (rc != 0)
return rc;
rc = tcp_test();
if (rc != 0)
return rc;
return 0;
}
#else
int dummy_sock_test;
#endif