blob: 19b769cb0f06d66e03b72468c0a89f2c29047537 [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
22void app_perror(const char *msg, pj_status_t rc)
23{
24 char errbuf[256];
25
26 PJ_CHECK_STACK();
27
28 pj_strerror(rc, errbuf, sizeof(errbuf));
29 PJ_LOG(1,("test", "%s: [pj_status_t=%d] %s", msg, rc, errbuf));
30}
31
32#define SERVER 0
33#define CLIENT 1
34
35pj_status_t app_socket(int family, int type, int proto, int port,
36 pj_sock_t *ptr_sock)
37{
38 pj_sockaddr_in addr;
39 pj_sock_t sock;
40 pj_status_t rc;
41
42 rc = pj_sock_socket(family, type, proto, &sock);
43 if (rc != PJ_SUCCESS)
44 return rc;
45
46 pj_memset(&addr, 0, sizeof(addr));
47 addr.sin_family = (pj_uint16_t)family;
48 addr.sin_port = (short)(port!=-1 ? pj_htons((pj_uint16_t)port) : 0);
49 rc = pj_sock_bind(sock, &addr, sizeof(addr));
50 if (rc != PJ_SUCCESS)
51 return rc;
52
Benny Prijono3d327302006-02-08 11:14:03 +000053#if PJ_HAS_TCP
Benny Prijono5dcb38d2005-11-21 01:55:47 +000054 if (type == PJ_SOCK_STREAM) {
55 rc = pj_sock_listen(sock, 5);
56 if (rc != PJ_SUCCESS)
57 return rc;
58 }
Benny Prijono3d327302006-02-08 11:14:03 +000059#endif
Benny Prijono5dcb38d2005-11-21 01:55:47 +000060
61 *ptr_sock = sock;
62 return PJ_SUCCESS;
63}
64
65pj_status_t app_socketpair(int family, int type, int protocol,
66 pj_sock_t *serverfd, pj_sock_t *clientfd)
67{
68 int i;
69 static unsigned short port = 11000;
70 pj_sockaddr_in addr;
71 pj_str_t s;
72 pj_status_t rc = 0;
73 pj_sock_t sock[2];
74
75 /* Create both sockets. */
76 for (i=0; i<2; ++i) {
77 rc = pj_sock_socket(family, type, protocol, &sock[i]);
78 if (rc != PJ_SUCCESS) {
79 if (i==1)
80 pj_sock_close(sock[0]);
81 return rc;
82 }
83 }
84
85 /* Retry bind */
86 pj_memset(&addr, 0, sizeof(addr));
87 addr.sin_family = PJ_AF_INET;
88 for (i=0; i<5; ++i) {
89 addr.sin_port = pj_htons(port++);
90 rc = pj_sock_bind(sock[SERVER], &addr, sizeof(addr));
91 if (rc == PJ_SUCCESS)
92 break;
93 }
94
95 if (rc != PJ_SUCCESS)
96 goto on_error;
97
98 /* For TCP, listen the socket. */
Benny Prijono3d327302006-02-08 11:14:03 +000099#if PJ_HAS_TCP
Benny Prijono5dcb38d2005-11-21 01:55:47 +0000100 if (type == PJ_SOCK_STREAM) {
101 rc = pj_sock_listen(sock[SERVER], PJ_SOMAXCONN);
102 if (rc != PJ_SUCCESS)
103 goto on_error;
104 }
Benny Prijono3d327302006-02-08 11:14:03 +0000105#endif
Benny Prijono5dcb38d2005-11-21 01:55:47 +0000106
107 /* Connect client socket. */
108 addr.sin_addr = pj_inet_addr(pj_cstr(&s, "127.0.0.1"));
109 rc = pj_sock_connect(sock[CLIENT], &addr, sizeof(addr));
110 if (rc != PJ_SUCCESS)
111 goto on_error;
112
113 /* For TCP, must accept(), and get the new socket. */
Benny Prijono3d327302006-02-08 11:14:03 +0000114#if PJ_HAS_TCP
Benny Prijono5dcb38d2005-11-21 01:55:47 +0000115 if (type == PJ_SOCK_STREAM) {
116 pj_sock_t newserver;
117
118 rc = pj_sock_accept(sock[SERVER], &newserver, NULL, NULL);
119 if (rc != PJ_SUCCESS)
120 goto on_error;
121
122 /* Replace server socket with new socket. */
123 pj_sock_close(sock[SERVER]);
124 sock[SERVER] = newserver;
125 }
Benny Prijono3d327302006-02-08 11:14:03 +0000126#endif
Benny Prijono5dcb38d2005-11-21 01:55:47 +0000127
128 *serverfd = sock[SERVER];
129 *clientfd = sock[CLIENT];
130
131 return rc;
132
133on_error:
134 for (i=0; i<2; ++i)
135 pj_sock_close(sock[i]);
136 return rc;
137}