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