blob: ea1d465273d240e5a061bd66155c9133db36145d [file] [log] [blame]
Benny Prijono5dcb38d2005-11-21 01:55:47 +00001/* $Id$ */
2/*
3 * Copyright (C)2003-2006 Benny Prijono <benny@prijono.org>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19#include "test.h"
20#include <pjlib.h>
21
Benny Prijono42c5b9e2006-05-10 19:24:40 +000022#define THIS_FILE "util.c"
23
Benny Prijono5dcb38d2005-11-21 01:55:47 +000024void app_perror(const char *msg, pj_status_t rc)
25{
Benny Prijono42c5b9e2006-05-10 19:24:40 +000026 char errbuf[PJ_ERR_MSG_SIZE];
Benny Prijono5dcb38d2005-11-21 01:55:47 +000027
28 PJ_CHECK_STACK();
29
30 pj_strerror(rc, errbuf, sizeof(errbuf));
Benny Prijono42c5b9e2006-05-10 19:24:40 +000031 PJ_LOG(3,("test", "%s: [pj_status_t=%d] %s", msg, rc, errbuf));
Benny Prijono5dcb38d2005-11-21 01:55:47 +000032}
33
34#define SERVER 0
35#define CLIENT 1
36
37pj_status_t app_socket(int family, int type, int proto, int port,
38 pj_sock_t *ptr_sock)
39{
40 pj_sockaddr_in addr;
41 pj_sock_t sock;
42 pj_status_t rc;
43
44 rc = pj_sock_socket(family, type, proto, &sock);
45 if (rc != PJ_SUCCESS)
46 return rc;
47
48 pj_memset(&addr, 0, sizeof(addr));
49 addr.sin_family = (pj_uint16_t)family;
50 addr.sin_port = (short)(port!=-1 ? pj_htons((pj_uint16_t)port) : 0);
51 rc = pj_sock_bind(sock, &addr, sizeof(addr));
52 if (rc != PJ_SUCCESS)
53 return rc;
54
Benny Prijono3d327302006-02-08 11:14:03 +000055#if PJ_HAS_TCP
Benny Prijono5dcb38d2005-11-21 01:55:47 +000056 if (type == PJ_SOCK_STREAM) {
57 rc = pj_sock_listen(sock, 5);
58 if (rc != PJ_SUCCESS)
59 return rc;
60 }
Benny Prijono3d327302006-02-08 11:14:03 +000061#endif
Benny Prijono5dcb38d2005-11-21 01:55:47 +000062
63 *ptr_sock = sock;
64 return PJ_SUCCESS;
65}
66
67pj_status_t app_socketpair(int family, int type, int protocol,
68 pj_sock_t *serverfd, pj_sock_t *clientfd)
69{
70 int i;
71 static unsigned short port = 11000;
72 pj_sockaddr_in addr;
73 pj_str_t s;
74 pj_status_t rc = 0;
75 pj_sock_t sock[2];
76
77 /* Create both sockets. */
78 for (i=0; i<2; ++i) {
79 rc = pj_sock_socket(family, type, protocol, &sock[i]);
80 if (rc != PJ_SUCCESS) {
81 if (i==1)
82 pj_sock_close(sock[0]);
83 return rc;
84 }
85 }
86
87 /* Retry bind */
88 pj_memset(&addr, 0, sizeof(addr));
89 addr.sin_family = PJ_AF_INET;
90 for (i=0; i<5; ++i) {
91 addr.sin_port = pj_htons(port++);
92 rc = pj_sock_bind(sock[SERVER], &addr, sizeof(addr));
93 if (rc == PJ_SUCCESS)
94 break;
95 }
96
97 if (rc != PJ_SUCCESS)
98 goto on_error;
99
100 /* For TCP, listen the socket. */
Benny Prijono3d327302006-02-08 11:14:03 +0000101#if PJ_HAS_TCP
Benny Prijono5dcb38d2005-11-21 01:55:47 +0000102 if (type == PJ_SOCK_STREAM) {
103 rc = pj_sock_listen(sock[SERVER], PJ_SOMAXCONN);
104 if (rc != PJ_SUCCESS)
105 goto on_error;
106 }
Benny Prijono3d327302006-02-08 11:14:03 +0000107#endif
Benny Prijono5dcb38d2005-11-21 01:55:47 +0000108
109 /* Connect client socket. */
110 addr.sin_addr = pj_inet_addr(pj_cstr(&s, "127.0.0.1"));
111 rc = pj_sock_connect(sock[CLIENT], &addr, sizeof(addr));
112 if (rc != PJ_SUCCESS)
113 goto on_error;
114
115 /* For TCP, must accept(), and get the new socket. */
Benny Prijono3d327302006-02-08 11:14:03 +0000116#if PJ_HAS_TCP
Benny Prijono5dcb38d2005-11-21 01:55:47 +0000117 if (type == PJ_SOCK_STREAM) {
118 pj_sock_t newserver;
119
120 rc = pj_sock_accept(sock[SERVER], &newserver, NULL, NULL);
121 if (rc != PJ_SUCCESS)
122 goto on_error;
123
124 /* Replace server socket with new socket. */
125 pj_sock_close(sock[SERVER]);
126 sock[SERVER] = newserver;
127 }
Benny Prijono3d327302006-02-08 11:14:03 +0000128#endif
Benny Prijono5dcb38d2005-11-21 01:55:47 +0000129
130 *serverfd = sock[SERVER];
131 *clientfd = sock[CLIENT];
132
133 return rc;
134
135on_error:
136 for (i=0; i<2; ++i)
137 pj_sock_close(sock[i]);
138 return rc;
139}