~ubuntu-branches/ubuntu/wily/sflphone/wily

« back to all changes in this revision

Viewing changes to daemon/libs/pjproject-2.2.1/pjlib/src/pjlib-test/ssl_sock.c

  • Committer: Package Import Robot
  • Author(s): Jonathan Riddell
  • Date: 2015-01-07 14:51:16 UTC
  • mfrom: (4.3.5 sid)
  • Revision ID: package-import@ubuntu.com-20150107145116-yxnafinf4lrdvrmx
Tags: 1.4.1-0.1ubuntu1
* Merge with Debian, remaining changes:
 - Drop soprano, nepomuk build-dep
* Drop ubuntu patches, now upstream

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Id: ssl_sock.c 4537 2013-06-19 06:47:43Z riza $ */
 
2
/* 
 
3
 * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
 
4
 * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
 
5
 *
 
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
 
 
23
 
 
24
#define CERT_DIR                    "../build/"
 
25
#define CERT_CA_FILE                CERT_DIR "cacert.pem"
 
26
#define CERT_FILE                   CERT_DIR "cacert.pem"
 
27
#define CERT_PRIVKEY_FILE           CERT_DIR "privkey.pem"
 
28
#define CERT_PRIVKEY_PASS           ""
 
29
 
 
30
 
 
31
#if INCLUDE_SSLSOCK_TEST
 
32
 
 
33
/* Global vars */
 
34
static int clients_num;
 
35
 
 
36
struct send_key {
 
37
    pj_ioqueue_op_key_t op_key;
 
38
};
 
39
 
 
40
 
 
41
static int get_cipher_list(void) {
 
42
    pj_status_t status;
 
43
    pj_ssl_cipher ciphers[100];
 
44
    unsigned cipher_num;
 
45
    unsigned i;
 
46
 
 
47
    cipher_num = PJ_ARRAY_SIZE(ciphers);
 
48
    status = pj_ssl_cipher_get_availables(ciphers, &cipher_num);
 
49
    if (status != PJ_SUCCESS) {
 
50
        app_perror("...FAILED to get available ciphers", status);
 
51
        return status;
 
52
    }
 
53
 
 
54
    PJ_LOG(3, ("", "...Found %u ciphers:", cipher_num));
 
55
    for (i = 0; i < cipher_num; ++i) {
 
56
        const char* st;
 
57
        st = pj_ssl_cipher_name(ciphers[i]);
 
58
        if (st == NULL)
 
59
            st = "[Unknown]";
 
60
 
 
61
        PJ_LOG(3, ("", "...%3u: 0x%08x=%s", i+1, ciphers[i], st));
 
62
    }
 
63
 
 
64
    return PJ_SUCCESS;
 
65
}
 
66
 
 
67
 
 
68
struct test_state
 
69
{
 
70
    pj_pool_t      *pool;           /* pool                                 */
 
71
    pj_ioqueue_t   *ioqueue;        /* ioqueue                              */
 
72
    pj_bool_t       is_server;      /* server role flag                     */
 
73
    pj_bool_t       is_verbose;     /* verbose flag, e.g: cert info         */
 
74
    pj_bool_t       echo;           /* echo received data                   */
 
75
    pj_status_t     err;            /* error flag                           */
 
76
    pj_size_t       sent;           /* bytes sent                           */
 
77
    pj_size_t       recv;           /* bytes received                       */
 
78
    pj_uint8_t      read_buf[256];  /* read buffer                          */
 
79
    pj_bool_t       done;           /* test done flag                       */
 
80
    char           *send_str;       /* data to send once connected          */
 
81
    pj_size_t       send_str_len;   /* send data length                     */
 
82
    pj_bool_t       check_echo;     /* flag to compare sent & echoed data   */
 
83
    const char     *check_echo_ptr; /* pointer/cursor for comparing data    */
 
84
    struct send_key send_key;       /* send op key                          */
 
85
};
 
86
 
 
87
static void dump_ssl_info(const pj_ssl_sock_info *si)
 
88
{
 
89
    const char *tmp_st;
 
90
 
 
91
    /* Print cipher name */
 
92
    tmp_st = pj_ssl_cipher_name(si->cipher);
 
93
    if (tmp_st == NULL)
 
94
        tmp_st = "[Unknown]";
 
95
    PJ_LOG(3, ("", ".....Cipher: %s", tmp_st));
 
96
 
 
97
    /* Print remote certificate info and verification result */
 
98
    if (si->remote_cert_info && si->remote_cert_info->subject.info.slen) 
 
99
    {
 
100
        char buf[2048];
 
101
        const char *verif_msgs[32];
 
102
        unsigned verif_msg_cnt;
 
103
 
 
104
        /* Dump remote TLS certificate info */
 
105
        PJ_LOG(3, ("", ".....Remote certificate info:"));
 
106
        pj_ssl_cert_info_dump(si->remote_cert_info, "  ", buf, sizeof(buf));
 
107
        PJ_LOG(3,("", "\n%s", buf));
 
108
 
 
109
        /* Dump remote TLS certificate verification result */
 
110
        verif_msg_cnt = PJ_ARRAY_SIZE(verif_msgs);
 
111
        pj_ssl_cert_get_verify_status_strings(si->verify_status,
 
112
                                              verif_msgs, &verif_msg_cnt);
 
113
        PJ_LOG(3,("", ".....Remote certificate verification result: %s",
 
114
                  (verif_msg_cnt == 1? verif_msgs[0]:"")));
 
115
        if (verif_msg_cnt > 1) {
 
116
            unsigned i;
 
117
            for (i = 0; i < verif_msg_cnt; ++i)
 
118
                PJ_LOG(3,("", "..... - %s", verif_msgs[i]));
 
119
        }
 
120
    }
 
121
}
 
122
 
 
123
 
 
124
static pj_bool_t ssl_on_connect_complete(pj_ssl_sock_t *ssock,
 
125
                                         pj_status_t status)
 
126
{
 
127
    struct test_state *st = (struct test_state*) 
 
128
                            pj_ssl_sock_get_user_data(ssock);
 
129
    void *read_buf[1];
 
130
    pj_ssl_sock_info info;
 
131
    char buf1[64], buf2[64];
 
132
 
 
133
    if (status != PJ_SUCCESS) {
 
134
        app_perror("...ERROR ssl_on_connect_complete()", status);
 
135
        goto on_return;
 
136
    }
 
137
 
 
138
    status = pj_ssl_sock_get_info(ssock, &info);
 
139
    if (status != PJ_SUCCESS) {
 
140
        app_perror("...ERROR pj_ssl_sock_get_info()", status);
 
141
        goto on_return;
 
142
    }
 
143
 
 
144
    pj_sockaddr_print((pj_sockaddr_t*)&info.local_addr, buf1, sizeof(buf1), 1);
 
145
    pj_sockaddr_print((pj_sockaddr_t*)&info.remote_addr, buf2, sizeof(buf2), 1);
 
146
    PJ_LOG(3, ("", "...Connected %s -> %s!", buf1, buf2));
 
147
 
 
148
    if (st->is_verbose)
 
149
        dump_ssl_info(&info);
 
150
 
 
151
    /* Start reading data */
 
152
    read_buf[0] = st->read_buf;
 
153
    status = pj_ssl_sock_start_read2(ssock, st->pool, sizeof(st->read_buf), (void**)read_buf, 0);
 
154
    if (status != PJ_SUCCESS) {
 
155
        app_perror("...ERROR pj_ssl_sock_start_read2()", status);
 
156
        goto on_return;
 
157
    }
 
158
 
 
159
    /* Start sending data */
 
160
    while (st->sent < st->send_str_len) {
 
161
        pj_ssize_t size;
 
162
 
 
163
        size = st->send_str_len - st->sent;
 
164
        status = pj_ssl_sock_send(ssock, (pj_ioqueue_op_key_t*)&st->send_key, 
 
165
                                  st->send_str + st->sent, &size, 0);
 
166
        if (status != PJ_SUCCESS && status != PJ_EPENDING) {
 
167
            app_perror("...ERROR pj_ssl_sock_send()", status);
 
168
            goto on_return;
 
169
        }
 
170
 
 
171
        if (status == PJ_SUCCESS)
 
172
            st->sent += size;
 
173
        else
 
174
            break;
 
175
    }
 
176
 
 
177
on_return:
 
178
    st->err = status;
 
179
 
 
180
    if (st->err != PJ_SUCCESS) {
 
181
        pj_ssl_sock_close(ssock);
 
182
        clients_num--;
 
183
        return PJ_FALSE;
 
184
    }
 
185
 
 
186
    return PJ_TRUE;
 
187
}
 
188
 
 
189
 
 
190
static pj_bool_t ssl_on_accept_complete(pj_ssl_sock_t *ssock,
 
191
                                        pj_ssl_sock_t *newsock,
 
192
                                        const pj_sockaddr_t *src_addr,
 
193
                                        int src_addr_len)
 
194
{
 
195
    struct test_state *parent_st = (struct test_state*) 
 
196
                                   pj_ssl_sock_get_user_data(ssock);
 
197
    struct test_state *st;
 
198
    void *read_buf[1];
 
199
    pj_ssl_sock_info info;
 
200
    char buf[64];
 
201
    pj_status_t status;
 
202
 
 
203
    PJ_UNUSED_ARG(src_addr_len);
 
204
 
 
205
    /* Duplicate parent test state to newly accepted test state */
 
206
    st = (struct test_state*)pj_pool_zalloc(parent_st->pool, sizeof(struct test_state));
 
207
    *st = *parent_st;
 
208
    pj_ssl_sock_set_user_data(newsock, st);
 
209
 
 
210
    status = pj_ssl_sock_get_info(newsock, &info);
 
211
    if (status != PJ_SUCCESS) {
 
212
        app_perror("...ERROR pj_ssl_sock_get_info()", status);
 
213
        goto on_return;
 
214
    }
 
215
 
 
216
    pj_sockaddr_print(src_addr, buf, sizeof(buf), 1);
 
217
    PJ_LOG(3, ("", "...Accepted connection from %s", buf));
 
218
 
 
219
    if (st->is_verbose)
 
220
        dump_ssl_info(&info);
 
221
 
 
222
    /* Start reading data */
 
223
    read_buf[0] = st->read_buf;
 
224
    status = pj_ssl_sock_start_read2(newsock, st->pool, sizeof(st->read_buf), (void**)read_buf, 0);
 
225
    if (status != PJ_SUCCESS) {
 
226
        app_perror("...ERROR pj_ssl_sock_start_read2()", status);
 
227
        goto on_return;
 
228
    }
 
229
 
 
230
    /* Start sending data */
 
231
    while (st->sent < st->send_str_len) {
 
232
        pj_ssize_t size;
 
233
 
 
234
        size = st->send_str_len - st->sent;
 
235
        status = pj_ssl_sock_send(newsock, (pj_ioqueue_op_key_t*)&st->send_key, 
 
236
                                  st->send_str + st->sent, &size, 0);
 
237
        if (status != PJ_SUCCESS && status != PJ_EPENDING) {
 
238
            app_perror("...ERROR pj_ssl_sock_send()", status);
 
239
            goto on_return;
 
240
        }
 
241
 
 
242
        if (status == PJ_SUCCESS)
 
243
            st->sent += size;
 
244
        else
 
245
            break;
 
246
    }
 
247
 
 
248
on_return:
 
249
    st->err = status;
 
250
 
 
251
    if (st->err != PJ_SUCCESS) {
 
252
        pj_ssl_sock_close(newsock);
 
253
        return PJ_FALSE;
 
254
    }
 
255
 
 
256
    return PJ_TRUE;
 
257
}
 
258
 
 
259
static pj_bool_t ssl_on_data_read(pj_ssl_sock_t *ssock,
 
260
                                  void *data,
 
261
                                  pj_size_t size,
 
262
                                  pj_status_t status,
 
263
                                  pj_size_t *remainder)
 
264
{
 
265
    struct test_state *st = (struct test_state*) 
 
266
                             pj_ssl_sock_get_user_data(ssock);
 
267
 
 
268
    PJ_UNUSED_ARG(remainder);
 
269
    PJ_UNUSED_ARG(data);
 
270
 
 
271
    if (size > 0) {
 
272
        pj_size_t consumed;
 
273
 
 
274
        /* Set random remainder */
 
275
        *remainder = pj_rand() % 100;
 
276
 
 
277
        /* Apply zero remainder if:
 
278
         * - remainder is less than size, or
 
279
         * - connection closed/error
 
280
         * - echo/check_eco set
 
281
         */
 
282
        if (*remainder > size || status != PJ_SUCCESS || st->echo || st->check_echo)
 
283
            *remainder = 0;
 
284
 
 
285
        consumed = size - *remainder;
 
286
        st->recv += consumed;
 
287
 
 
288
        //printf("%.*s", consumed, (char*)data);
 
289
 
 
290
        pj_memmove(data, (char*)data + consumed, *remainder);
 
291
 
 
292
        /* Echo data when specified to */
 
293
        if (st->echo) {
 
294
            pj_ssize_t size_ = consumed;
 
295
            status = pj_ssl_sock_send(ssock, (pj_ioqueue_op_key_t*)&st->send_key, data, &size_, 0);
 
296
            if (status != PJ_SUCCESS && status != PJ_EPENDING) {
 
297
                app_perror("...ERROR pj_ssl_sock_send()", status);
 
298
                goto on_return;
 
299
            }
 
300
 
 
301
            if (status == PJ_SUCCESS)
 
302
                st->sent += size_;
 
303
        }
 
304
 
 
305
        /* Verify echoed data when specified to */
 
306
        if (st->check_echo) {
 
307
            if (!st->check_echo_ptr)
 
308
                st->check_echo_ptr = st->send_str;
 
309
 
 
310
            if (pj_memcmp(st->check_echo_ptr, data, consumed)) {
 
311
                status = PJ_EINVAL;
 
312
                app_perror("...ERROR echoed data not exact", status);
 
313
                goto on_return;
 
314
            }
 
315
            st->check_echo_ptr += consumed;
 
316
 
 
317
            /* Echo received completely */
 
318
            if (st->send_str_len == st->recv) {
 
319
                pj_ssl_sock_info info;
 
320
                char buf[64];
 
321
 
 
322
                status = pj_ssl_sock_get_info(ssock, &info);
 
323
                if (status != PJ_SUCCESS) {
 
324
                    app_perror("...ERROR pj_ssl_sock_get_info()", status);
 
325
                    goto on_return;
 
326
                }
 
327
 
 
328
                pj_sockaddr_print((pj_sockaddr_t*)&info.local_addr, buf, sizeof(buf), 1);
 
329
                PJ_LOG(3, ("", "...%s successfully recv %d bytes echo", buf, st->recv));
 
330
                st->done = PJ_TRUE;
 
331
            }
 
332
        }
 
333
    }
 
334
 
 
335
    if (status != PJ_SUCCESS) {
 
336
        if (status == PJ_EEOF) {
 
337
            status = PJ_SUCCESS;
 
338
            st->done = PJ_TRUE;
 
339
        } else {
 
340
            app_perror("...ERROR ssl_on_data_read()", status);
 
341
        }
 
342
    }
 
343
 
 
344
on_return:
 
345
    st->err = status;
 
346
 
 
347
    if (st->err != PJ_SUCCESS || st->done) {
 
348
        pj_ssl_sock_close(ssock);
 
349
        if (!st->is_server)
 
350
            clients_num--;
 
351
        return PJ_FALSE;
 
352
    }
 
353
 
 
354
    return PJ_TRUE;
 
355
}
 
356
 
 
357
static pj_bool_t ssl_on_data_sent(pj_ssl_sock_t *ssock,
 
358
                                  pj_ioqueue_op_key_t *op_key,
 
359
                                  pj_ssize_t sent)
 
360
{
 
361
    struct test_state *st = (struct test_state*)
 
362
                             pj_ssl_sock_get_user_data(ssock);
 
363
    PJ_UNUSED_ARG(op_key);
 
364
 
 
365
    if (sent < 0) {
 
366
        st->err = (pj_status_t)-sent;
 
367
    } else {
 
368
        st->sent += sent;
 
369
 
 
370
        /* Send more if any */
 
371
        while (st->sent < st->send_str_len) {
 
372
            pj_ssize_t size;
 
373
            pj_status_t status;
 
374
 
 
375
            size = st->send_str_len - st->sent;
 
376
            status = pj_ssl_sock_send(ssock, (pj_ioqueue_op_key_t*)&st->send_key, 
 
377
                                      st->send_str + st->sent, &size, 0);
 
378
            if (status != PJ_SUCCESS && status != PJ_EPENDING) {
 
379
                app_perror("...ERROR pj_ssl_sock_send()", status);
 
380
                st->err = status;
 
381
                break;
 
382
            }
 
383
 
 
384
            if (status == PJ_SUCCESS)
 
385
                st->sent += size;
 
386
            else
 
387
                break;
 
388
        }
 
389
    }
 
390
 
 
391
    if (st->err != PJ_SUCCESS) {
 
392
        pj_ssl_sock_close(ssock);
 
393
        if (!st->is_server)
 
394
            clients_num--;
 
395
        return PJ_FALSE;
 
396
    }
 
397
 
 
398
    return PJ_TRUE;
 
399
}
 
400
 
 
401
#define HTTP_REQ                "GET / HTTP/1.0\r\n\r\n";
 
402
#define HTTP_SERVER_ADDR        "trac.pjsip.org"
 
403
#define HTTP_SERVER_PORT        443
 
404
 
 
405
static int https_client_test(unsigned ms_timeout)
 
406
{
 
407
    pj_pool_t *pool = NULL;
 
408
    pj_ioqueue_t *ioqueue = NULL;
 
409
    pj_timer_heap_t *timer = NULL;
 
410
    pj_ssl_sock_t *ssock = NULL;
 
411
    pj_ssl_sock_param param;
 
412
    pj_status_t status;
 
413
    struct test_state state = {0};
 
414
    pj_sockaddr local_addr, rem_addr;
 
415
    pj_str_t tmp_st;
 
416
 
 
417
    pool = pj_pool_create(mem, "https_get", 256, 256, NULL);
 
418
 
 
419
    status = pj_ioqueue_create(pool, 4, &ioqueue);
 
420
    if (status != PJ_SUCCESS) {
 
421
        goto on_return;
 
422
    }
 
423
 
 
424
    status = pj_timer_heap_create(pool, 4, &timer);
 
425
    if (status != PJ_SUCCESS) {
 
426
        goto on_return;
 
427
    }
 
428
 
 
429
    state.pool = pool;
 
430
    state.send_str = HTTP_REQ;
 
431
    state.send_str_len = pj_ansi_strlen(state.send_str);
 
432
    state.is_verbose = PJ_TRUE;
 
433
 
 
434
    pj_ssl_sock_param_default(&param);
 
435
    param.cb.on_connect_complete = &ssl_on_connect_complete;
 
436
    param.cb.on_data_read = &ssl_on_data_read;
 
437
    param.cb.on_data_sent = &ssl_on_data_sent;
 
438
    param.ioqueue = ioqueue;
 
439
    param.user_data = &state;
 
440
    param.server_name = pj_str((char*)HTTP_SERVER_ADDR);
 
441
    param.timer_heap = timer;
 
442
    param.timeout.sec = 0;
 
443
    param.timeout.msec = ms_timeout;
 
444
    param.proto = PJ_SSL_SOCK_PROTO_SSL23;
 
445
    pj_time_val_normalize(&param.timeout);
 
446
 
 
447
    status = pj_ssl_sock_create(pool, &param, &ssock);
 
448
    if (status != PJ_SUCCESS) {
 
449
        goto on_return;
 
450
    }
 
451
 
 
452
    pj_sockaddr_init(PJ_AF_INET, &local_addr, pj_strset2(&tmp_st, "0.0.0.0"), 0);
 
453
    pj_sockaddr_init(PJ_AF_INET, &rem_addr, pj_strset2(&tmp_st, HTTP_SERVER_ADDR), HTTP_SERVER_PORT);
 
454
    status = pj_ssl_sock_start_connect(ssock, pool, &local_addr, &rem_addr, sizeof(rem_addr));
 
455
    if (status == PJ_SUCCESS) {
 
456
        ssl_on_connect_complete(ssock, PJ_SUCCESS);
 
457
    } else if (status == PJ_EPENDING) {
 
458
        status = PJ_SUCCESS;
 
459
    } else {
 
460
        goto on_return;
 
461
    }
 
462
 
 
463
    /* Wait until everything has been sent/received */
 
464
    while (state.err == PJ_SUCCESS && !state.done) {
 
465
#ifdef PJ_SYMBIAN
 
466
        pj_symbianos_poll(-1, 1000);
 
467
#else
 
468
        pj_time_val delay = {0, 100};
 
469
        pj_ioqueue_poll(ioqueue, &delay);
 
470
        pj_timer_heap_poll(timer, &delay);
 
471
#endif
 
472
    }
 
473
 
 
474
    if (state.err) {
 
475
        status = state.err;
 
476
        goto on_return;
 
477
    }
 
478
 
 
479
    PJ_LOG(3, ("", "...Done!"));
 
480
    PJ_LOG(3, ("", ".....Sent/recv: %d/%d bytes", state.sent, state.recv));
 
481
 
 
482
on_return:
 
483
    if (ssock && !state.err && !state.done) 
 
484
        pj_ssl_sock_close(ssock);
 
485
    if (ioqueue)
 
486
        pj_ioqueue_destroy(ioqueue);
 
487
    if (timer)
 
488
        pj_timer_heap_destroy(timer);
 
489
    if (pool)
 
490
        pj_pool_release(pool);
 
491
 
 
492
    return status;
 
493
}
 
494
 
 
495
 
 
496
static int echo_test(pj_ssl_sock_proto srv_proto, pj_ssl_sock_proto cli_proto,
 
497
                     pj_ssl_cipher srv_cipher, pj_ssl_cipher cli_cipher,
 
498
                     pj_bool_t req_client_cert, pj_bool_t client_provide_cert)
 
499
{
 
500
    pj_pool_t *pool = NULL;
 
501
    pj_ioqueue_t *ioqueue = NULL;
 
502
    pj_ssl_sock_t *ssock_serv = NULL;
 
503
    pj_ssl_sock_t *ssock_cli = NULL;
 
504
    pj_ssl_sock_param param;
 
505
    struct test_state state_serv = { 0 };
 
506
    struct test_state state_cli = { 0 };
 
507
    pj_sockaddr addr, listen_addr;
 
508
    pj_ssl_cipher ciphers[1];
 
509
    pj_ssl_cert_t *cert = NULL;
 
510
    pj_status_t status;
 
511
 
 
512
    pool = pj_pool_create(mem, "ssl_echo", 256, 256, NULL);
 
513
 
 
514
    status = pj_ioqueue_create(pool, 4, &ioqueue);
 
515
    if (status != PJ_SUCCESS) {
 
516
        goto on_return;
 
517
    }
 
518
 
 
519
    pj_ssl_sock_param_default(&param);
 
520
    param.cb.on_accept_complete = &ssl_on_accept_complete;
 
521
    param.cb.on_connect_complete = &ssl_on_connect_complete;
 
522
    param.cb.on_data_read = &ssl_on_data_read;
 
523
    param.cb.on_data_sent = &ssl_on_data_sent;
 
524
    param.ioqueue = ioqueue;
 
525
    param.ciphers = ciphers;
 
526
 
 
527
    /* Init default bind address */
 
528
    {
 
529
        pj_str_t tmp_st;
 
530
        pj_sockaddr_init(PJ_AF_INET, &addr, pj_strset2(&tmp_st, "127.0.0.1"), 0);
 
531
    }
 
532
 
 
533
    /* === SERVER === */
 
534
    param.proto = srv_proto;
 
535
    param.user_data = &state_serv;
 
536
    param.ciphers_num = (srv_cipher == -1)? 0 : 1;
 
537
    param.require_client_cert = req_client_cert;
 
538
    ciphers[0] = srv_cipher;
 
539
 
 
540
    state_serv.pool = pool;
 
541
    state_serv.echo = PJ_TRUE;
 
542
    state_serv.is_server = PJ_TRUE;
 
543
    state_serv.is_verbose = PJ_TRUE;
 
544
 
 
545
    status = pj_ssl_sock_create(pool, &param, &ssock_serv);
 
546
    if (status != PJ_SUCCESS) {
 
547
        goto on_return;
 
548
    }
 
549
 
 
550
    /* Set server cert */
 
551
    {
 
552
        pj_str_t tmp1, tmp2, tmp3, tmp4;
 
553
 
 
554
        status = pj_ssl_cert_load_from_files(pool, 
 
555
                                             pj_strset2(&tmp1, (char*)CERT_CA_FILE), 
 
556
                                             pj_strset2(&tmp2, (char*)CERT_FILE), 
 
557
                                             pj_strset2(&tmp3, (char*)CERT_PRIVKEY_FILE), 
 
558
                                             pj_strset2(&tmp4, (char*)CERT_PRIVKEY_PASS), 
 
559
                                             &cert);
 
560
        if (status != PJ_SUCCESS) {
 
561
            goto on_return;
 
562
        }
 
563
 
 
564
        status = pj_ssl_sock_set_certificate(ssock_serv, pool, cert);
 
565
        if (status != PJ_SUCCESS) {
 
566
            goto on_return;
 
567
        }
 
568
    }
 
569
 
 
570
    status = pj_ssl_sock_start_accept(ssock_serv, pool, &addr, pj_sockaddr_get_len(&addr));
 
571
    if (status != PJ_SUCCESS) {
 
572
        goto on_return;
 
573
    }
 
574
 
 
575
    /* Get listener address */
 
576
    {
 
577
        pj_ssl_sock_info info;
 
578
 
 
579
        pj_ssl_sock_get_info(ssock_serv, &info);
 
580
        pj_sockaddr_cp(&listen_addr, &info.local_addr);
 
581
    }
 
582
 
 
583
    /* === CLIENT === */
 
584
    param.proto = cli_proto;
 
585
    param.user_data = &state_cli;
 
586
    param.ciphers_num = (cli_cipher == -1)? 0 : 1;
 
587
    ciphers[0] = cli_cipher;
 
588
 
 
589
    state_cli.pool = pool;
 
590
    state_cli.check_echo = PJ_TRUE;
 
591
    state_cli.is_verbose = PJ_TRUE;
 
592
 
 
593
    {
 
594
        pj_time_val now;
 
595
 
 
596
        pj_gettimeofday(&now);
 
597
        pj_srand((unsigned)now.sec);
 
598
        state_cli.send_str_len = (pj_rand() % 5 + 1) * 1024 + pj_rand() % 1024;
 
599
    }
 
600
    state_cli.send_str = (char*)pj_pool_alloc(pool, state_cli.send_str_len);
 
601
    {
 
602
        unsigned i;
 
603
        for (i = 0; i < state_cli.send_str_len; ++i)
 
604
            state_cli.send_str[i] = (char)(pj_rand() % 256);
 
605
    }
 
606
 
 
607
    status = pj_ssl_sock_create(pool, &param, &ssock_cli);
 
608
    if (status != PJ_SUCCESS) {
 
609
        goto on_return;
 
610
    }
 
611
 
 
612
    /* Set cert for client */
 
613
    {
 
614
 
 
615
        if (!client_provide_cert) {
 
616
            pj_str_t tmp1, tmp2;
 
617
 
 
618
            pj_strset2(&tmp1, (char*)CERT_CA_FILE);
 
619
            pj_strset2(&tmp2, NULL);
 
620
            status = pj_ssl_cert_load_from_files(pool, 
 
621
                                                 &tmp1, &tmp2, &tmp2, &tmp2,
 
622
                                                 &cert);
 
623
            if (status != PJ_SUCCESS) {
 
624
                goto on_return;
 
625
            }
 
626
        }
 
627
 
 
628
        status = pj_ssl_sock_set_certificate(ssock_cli, pool, cert);
 
629
        if (status != PJ_SUCCESS) {
 
630
            goto on_return;
 
631
        }
 
632
    }
 
633
 
 
634
    status = pj_ssl_sock_start_connect(ssock_cli, pool, &addr, &listen_addr, pj_sockaddr_get_len(&addr));
 
635
    if (status == PJ_SUCCESS) {
 
636
        ssl_on_connect_complete(ssock_cli, PJ_SUCCESS);
 
637
    } else if (status == PJ_EPENDING) {
 
638
        status = PJ_SUCCESS;
 
639
    } else {
 
640
        goto on_return;
 
641
    }
 
642
 
 
643
    /* Wait until everything has been sent/received or error */
 
644
    while (!state_serv.err && !state_cli.err && !state_serv.done && !state_cli.done)
 
645
    {
 
646
#ifdef PJ_SYMBIAN
 
647
        pj_symbianos_poll(-1, 1000);
 
648
#else
 
649
        pj_time_val delay = {0, 100};
 
650
        pj_ioqueue_poll(ioqueue, &delay);
 
651
#endif
 
652
    }
 
653
 
 
654
    /* Clean up sockets */
 
655
    {
 
656
        pj_time_val delay = {0, 100};
 
657
        while (pj_ioqueue_poll(ioqueue, &delay) > 0);
 
658
    }
 
659
 
 
660
    if (state_serv.err || state_cli.err) {
 
661
        if (state_serv.err != PJ_SUCCESS)
 
662
            status = state_serv.err;
 
663
        else
 
664
            status = state_cli.err;
 
665
 
 
666
        goto on_return;
 
667
    }
 
668
 
 
669
    PJ_LOG(3, ("", "...Done!"));
 
670
    PJ_LOG(3, ("", ".....Sent/recv: %d/%d bytes", state_cli.sent, state_cli.recv));
 
671
 
 
672
on_return:
 
673
    if (ssock_serv)
 
674
        pj_ssl_sock_close(ssock_serv);
 
675
    if (ssock_cli && !state_cli.err && !state_cli.done) 
 
676
        pj_ssl_sock_close(ssock_cli);
 
677
    if (ioqueue)
 
678
        pj_ioqueue_destroy(ioqueue);
 
679
    if (pool)
 
680
        pj_pool_release(pool);
 
681
 
 
682
    return status;
 
683
}
 
684
 
 
685
 
 
686
static pj_bool_t asock_on_data_read(pj_activesock_t *asock,
 
687
                                    void *data,
 
688
                                    pj_size_t size,
 
689
                                    pj_status_t status,
 
690
                                    pj_size_t *remainder)
 
691
{
 
692
    struct test_state *st = (struct test_state*)
 
693
                             pj_activesock_get_user_data(asock);
 
694
 
 
695
    PJ_UNUSED_ARG(data);
 
696
    PJ_UNUSED_ARG(size);
 
697
    PJ_UNUSED_ARG(remainder);
 
698
 
 
699
    if (status != PJ_SUCCESS) {
 
700
        if (status == PJ_EEOF) {
 
701
            status = PJ_SUCCESS;
 
702
            st->done = PJ_TRUE;
 
703
        } else {
 
704
            app_perror("...ERROR asock_on_data_read()", status);
 
705
        }
 
706
    }
 
707
 
 
708
    st->err = status;
 
709
 
 
710
    if (st->err != PJ_SUCCESS || st->done) {
 
711
        pj_activesock_close(asock);
 
712
        if (!st->is_server)
 
713
            clients_num--;
 
714
        return PJ_FALSE;
 
715
    }
 
716
 
 
717
    return PJ_TRUE;
 
718
}
 
719
 
 
720
 
 
721
static pj_bool_t asock_on_connect_complete(pj_activesock_t *asock,
 
722
                                           pj_status_t status)
 
723
{
 
724
    struct test_state *st = (struct test_state*)
 
725
                             pj_activesock_get_user_data(asock);
 
726
 
 
727
    if (status == PJ_SUCCESS) {
 
728
        void *read_buf[1];
 
729
 
 
730
        /* Start reading data */
 
731
        read_buf[0] = st->read_buf;
 
732
        status = pj_activesock_start_read2(asock, st->pool, sizeof(st->read_buf), (void**)read_buf, 0);
 
733
        if (status != PJ_SUCCESS) {
 
734
            app_perror("...ERROR pj_ssl_sock_start_read2()", status);
 
735
        }
 
736
    }
 
737
 
 
738
    st->err = status;
 
739
 
 
740
    if (st->err != PJ_SUCCESS) {
 
741
        pj_activesock_close(asock);
 
742
        if (!st->is_server)
 
743
            clients_num--;
 
744
        return PJ_FALSE;
 
745
    }
 
746
 
 
747
    return PJ_TRUE;
 
748
}
 
749
 
 
750
static pj_bool_t asock_on_accept_complete(pj_activesock_t *asock,
 
751
                                          pj_sock_t newsock,
 
752
                                          const pj_sockaddr_t *src_addr,
 
753
                                          int src_addr_len)
 
754
{
 
755
    struct test_state *st;
 
756
    void *read_buf[1];
 
757
    pj_activesock_t *new_asock;
 
758
    pj_activesock_cb asock_cb = { 0 };
 
759
    pj_status_t status;
 
760
 
 
761
    PJ_UNUSED_ARG(src_addr);
 
762
    PJ_UNUSED_ARG(src_addr_len);
 
763
 
 
764
    st = (struct test_state*) pj_activesock_get_user_data(asock);
 
765
 
 
766
    asock_cb.on_data_read = &asock_on_data_read;
 
767
    status = pj_activesock_create(st->pool, newsock, pj_SOCK_STREAM(), NULL, 
 
768
                                  st->ioqueue, &asock_cb, st, &new_asock);
 
769
    if (status != PJ_SUCCESS) {
 
770
        goto on_return;
 
771
    }
 
772
 
 
773
    /* Start reading data */
 
774
    read_buf[0] = st->read_buf;
 
775
    status = pj_activesock_start_read2(new_asock, st->pool, 
 
776
                                       sizeof(st->read_buf), 
 
777
                                       (void**)read_buf, 0);
 
778
    if (status != PJ_SUCCESS) {
 
779
        app_perror("...ERROR pj_ssl_sock_start_read2()", status);
 
780
    }
 
781
 
 
782
on_return:
 
783
    st->err = status;
 
784
 
 
785
    if (st->err != PJ_SUCCESS)
 
786
        pj_activesock_close(new_asock);
 
787
 
 
788
    return PJ_TRUE;
 
789
}
 
790
 
 
791
 
 
792
/* Raw TCP socket try to connect to SSL socket server, once
 
793
 * connection established, it will just do nothing, SSL socket
 
794
 * server should be able to close the connection after specified
 
795
 * timeout period (set ms_timeout to 0 to disable timer).
 
796
 */
 
797
static int client_non_ssl(unsigned ms_timeout)
 
798
{
 
799
    pj_pool_t *pool = NULL;
 
800
    pj_ioqueue_t *ioqueue = NULL;
 
801
    pj_timer_heap_t *timer = NULL;
 
802
    pj_ssl_sock_t *ssock_serv = NULL;
 
803
    pj_activesock_t *asock_cli = NULL;
 
804
    pj_activesock_cb asock_cb = { 0 };
 
805
    pj_sock_t sock = PJ_INVALID_SOCKET;
 
806
    pj_ssl_sock_param param;
 
807
    struct test_state state_serv = { 0 };
 
808
    struct test_state state_cli = { 0 };
 
809
    pj_sockaddr listen_addr;
 
810
    pj_ssl_cert_t *cert = NULL;
 
811
    pj_status_t status;
 
812
 
 
813
    pool = pj_pool_create(mem, "ssl_accept_raw_tcp", 256, 256, NULL);
 
814
 
 
815
    status = pj_ioqueue_create(pool, 4, &ioqueue);
 
816
    if (status != PJ_SUCCESS) {
 
817
        goto on_return;
 
818
    }
 
819
 
 
820
    status = pj_timer_heap_create(pool, 4, &timer);
 
821
    if (status != PJ_SUCCESS) {
 
822
        goto on_return;
 
823
    }
 
824
 
 
825
    /* Set cert */
 
826
    {
 
827
        pj_str_t tmp1, tmp2, tmp3, tmp4;
 
828
        status = pj_ssl_cert_load_from_files(pool, 
 
829
                                             pj_strset2(&tmp1, (char*)CERT_CA_FILE), 
 
830
                                             pj_strset2(&tmp2, (char*)CERT_FILE), 
 
831
                                             pj_strset2(&tmp3, (char*)CERT_PRIVKEY_FILE), 
 
832
                                             pj_strset2(&tmp4, (char*)CERT_PRIVKEY_PASS), 
 
833
                                             &cert);
 
834
        if (status != PJ_SUCCESS) {
 
835
            goto on_return;
 
836
        }
 
837
    }
 
838
 
 
839
    pj_ssl_sock_param_default(&param);
 
840
    param.cb.on_accept_complete = &ssl_on_accept_complete;
 
841
    param.cb.on_data_read = &ssl_on_data_read;
 
842
    param.cb.on_data_sent = &ssl_on_data_sent;
 
843
    param.ioqueue = ioqueue;
 
844
    param.timer_heap = timer;
 
845
    param.timeout.sec = 0;
 
846
    param.timeout.msec = ms_timeout;
 
847
    pj_time_val_normalize(&param.timeout);
 
848
 
 
849
    /* SERVER */
 
850
    param.user_data = &state_serv;
 
851
    state_serv.pool = pool;
 
852
    state_serv.is_server = PJ_TRUE;
 
853
    state_serv.is_verbose = PJ_TRUE;
 
854
 
 
855
    status = pj_ssl_sock_create(pool, &param, &ssock_serv);
 
856
    if (status != PJ_SUCCESS) {
 
857
        goto on_return;
 
858
    }
 
859
 
 
860
    status = pj_ssl_sock_set_certificate(ssock_serv, pool, cert);
 
861
    if (status != PJ_SUCCESS) {
 
862
        goto on_return;
 
863
    }
 
864
 
 
865
    /* Init bind address */
 
866
    {
 
867
        pj_str_t tmp_st;
 
868
        pj_sockaddr_init(PJ_AF_INET, &listen_addr, pj_strset2(&tmp_st, "127.0.0.1"), 0);
 
869
    }
 
870
 
 
871
    status = pj_ssl_sock_start_accept(ssock_serv, pool, &listen_addr, pj_sockaddr_get_len(&listen_addr));
 
872
    if (status != PJ_SUCCESS) {
 
873
        goto on_return;
 
874
    }
 
875
 
 
876
    /* Update listener address */
 
877
    {
 
878
        pj_ssl_sock_info info;
 
879
 
 
880
        pj_ssl_sock_get_info(ssock_serv, &info);
 
881
        pj_sockaddr_cp(&listen_addr, &info.local_addr);
 
882
    }
 
883
 
 
884
    /* CLIENT */
 
885
    state_cli.pool = pool;
 
886
    status = pj_sock_socket(pj_AF_INET(), pj_SOCK_STREAM(), 0, &sock);
 
887
    if (status != PJ_SUCCESS) {
 
888
        goto on_return;
 
889
    }
 
890
 
 
891
    asock_cb.on_connect_complete = &asock_on_connect_complete;
 
892
    asock_cb.on_data_read = &asock_on_data_read;
 
893
    status = pj_activesock_create(pool, sock, pj_SOCK_STREAM(), NULL, 
 
894
                                  ioqueue, &asock_cb, &state_cli, &asock_cli);
 
895
    if (status != PJ_SUCCESS) {
 
896
        goto on_return;
 
897
    }
 
898
 
 
899
    status = pj_activesock_start_connect(asock_cli, pool, (pj_sockaddr_t*)&listen_addr, 
 
900
                                         pj_sockaddr_get_len(&listen_addr));
 
901
    if (status == PJ_SUCCESS) {
 
902
        asock_on_connect_complete(asock_cli, PJ_SUCCESS);
 
903
    } else if (status == PJ_EPENDING) {
 
904
        status = PJ_SUCCESS;
 
905
    } else {
 
906
        goto on_return;
 
907
    }
 
908
 
 
909
    /* Wait until everything has been sent/received or error */
 
910
    while (!state_serv.err && !state_cli.err && !state_serv.done && !state_cli.done)
 
911
    {
 
912
#ifdef PJ_SYMBIAN
 
913
        pj_symbianos_poll(-1, 1000);
 
914
#else
 
915
        pj_time_val delay = {0, 100};
 
916
        pj_ioqueue_poll(ioqueue, &delay);
 
917
        pj_timer_heap_poll(timer, &delay);
 
918
#endif
 
919
    }
 
920
 
 
921
    if (state_serv.err || state_cli.err) {
 
922
        if (state_serv.err != PJ_SUCCESS)
 
923
            status = state_serv.err;
 
924
        else
 
925
            status = state_cli.err;
 
926
 
 
927
        goto on_return;
 
928
    }
 
929
 
 
930
    PJ_LOG(3, ("", "...Done!"));
 
931
 
 
932
on_return:
 
933
    if (ssock_serv)
 
934
        pj_ssl_sock_close(ssock_serv);
 
935
    if (asock_cli && !state_cli.err && !state_cli.done)
 
936
        pj_activesock_close(asock_cli);
 
937
    if (timer)
 
938
        pj_timer_heap_destroy(timer);
 
939
    if (ioqueue)
 
940
        pj_ioqueue_destroy(ioqueue);
 
941
    if (pool)
 
942
        pj_pool_release(pool);
 
943
 
 
944
    return status;
 
945
}
 
946
 
 
947
 
 
948
/* SSL socket try to connect to raw TCP socket server, once
 
949
 * connection established, SSL socket will try to perform SSL
 
950
 * handshake. SSL client socket should be able to close the
 
951
 * connection after specified timeout period (set ms_timeout to 
 
952
 * 0 to disable timer).
 
953
 */
 
954
static int server_non_ssl(unsigned ms_timeout)
 
955
{
 
956
    pj_pool_t *pool = NULL;
 
957
    pj_ioqueue_t *ioqueue = NULL;
 
958
    pj_timer_heap_t *timer = NULL;
 
959
    pj_activesock_t *asock_serv = NULL;
 
960
    pj_ssl_sock_t *ssock_cli = NULL;
 
961
    pj_activesock_cb asock_cb = { 0 };
 
962
    pj_sock_t sock = PJ_INVALID_SOCKET;
 
963
    pj_ssl_sock_param param;
 
964
    struct test_state state_serv = { 0 };
 
965
    struct test_state state_cli = { 0 };
 
966
    pj_sockaddr addr, listen_addr;
 
967
    pj_status_t status;
 
968
 
 
969
    pool = pj_pool_create(mem, "ssl_connect_raw_tcp", 256, 256, NULL);
 
970
 
 
971
    status = pj_ioqueue_create(pool, 4, &ioqueue);
 
972
    if (status != PJ_SUCCESS) {
 
973
        goto on_return;
 
974
    }
 
975
 
 
976
    status = pj_timer_heap_create(pool, 4, &timer);
 
977
    if (status != PJ_SUCCESS) {
 
978
        goto on_return;
 
979
    }
 
980
 
 
981
    /* SERVER */
 
982
    state_serv.pool = pool;
 
983
    state_serv.ioqueue = ioqueue;
 
984
 
 
985
    status = pj_sock_socket(pj_AF_INET(), pj_SOCK_STREAM(), 0, &sock);
 
986
    if (status != PJ_SUCCESS) {
 
987
        goto on_return;
 
988
    }
 
989
 
 
990
    /* Init bind address */
 
991
    {
 
992
        pj_str_t tmp_st;
 
993
        pj_sockaddr_init(PJ_AF_INET, &listen_addr, pj_strset2(&tmp_st, "127.0.0.1"), 0);
 
994
    }
 
995
 
 
996
    status = pj_sock_bind(sock, (pj_sockaddr_t*)&listen_addr, 
 
997
                          pj_sockaddr_get_len((pj_sockaddr_t*)&listen_addr));
 
998
    if (status != PJ_SUCCESS) {
 
999
        goto on_return;
 
1000
    }
 
1001
 
 
1002
    status = pj_sock_listen(sock, PJ_SOMAXCONN);
 
1003
    if (status != PJ_SUCCESS) {
 
1004
        goto on_return;
 
1005
    }
 
1006
 
 
1007
    asock_cb.on_accept_complete = &asock_on_accept_complete;
 
1008
    status = pj_activesock_create(pool, sock, pj_SOCK_STREAM(), NULL, 
 
1009
                                  ioqueue, &asock_cb, &state_serv, &asock_serv);
 
1010
    if (status != PJ_SUCCESS) {
 
1011
        goto on_return;
 
1012
    }
 
1013
 
 
1014
    status = pj_activesock_start_accept(asock_serv, pool);
 
1015
    if (status != PJ_SUCCESS)
 
1016
        goto on_return;
 
1017
 
 
1018
    /* Update listener address */
 
1019
    {
 
1020
        int addr_len;
 
1021
 
 
1022
        addr_len = sizeof(listen_addr);
 
1023
        pj_sock_getsockname(sock, (pj_sockaddr_t*)&listen_addr, &addr_len);
 
1024
    }
 
1025
 
 
1026
    /* CLIENT */
 
1027
    pj_ssl_sock_param_default(&param);
 
1028
    param.cb.on_connect_complete = &ssl_on_connect_complete;
 
1029
    param.cb.on_data_read = &ssl_on_data_read;
 
1030
    param.cb.on_data_sent = &ssl_on_data_sent;
 
1031
    param.ioqueue = ioqueue;
 
1032
    param.timer_heap = timer;
 
1033
    param.timeout.sec = 0;
 
1034
    param.timeout.msec = ms_timeout;
 
1035
    pj_time_val_normalize(&param.timeout);
 
1036
    param.user_data = &state_cli;
 
1037
 
 
1038
    state_cli.pool = pool;
 
1039
    state_cli.is_server = PJ_FALSE;
 
1040
    state_cli.is_verbose = PJ_TRUE;
 
1041
 
 
1042
    status = pj_ssl_sock_create(pool, &param, &ssock_cli);
 
1043
    if (status != PJ_SUCCESS) {
 
1044
        goto on_return;
 
1045
    }
 
1046
 
 
1047
    /* Init default bind address */
 
1048
    {
 
1049
        pj_str_t tmp_st;
 
1050
        pj_sockaddr_init(PJ_AF_INET, &addr, pj_strset2(&tmp_st, "127.0.0.1"), 0);
 
1051
    }
 
1052
 
 
1053
    status = pj_ssl_sock_start_connect(ssock_cli, pool, 
 
1054
                                       (pj_sockaddr_t*)&addr, 
 
1055
                                       (pj_sockaddr_t*)&listen_addr, 
 
1056
                                       pj_sockaddr_get_len(&listen_addr));
 
1057
    if (status != PJ_EPENDING) {
 
1058
        goto on_return;
 
1059
    }
 
1060
 
 
1061
    /* Wait until everything has been sent/received or error */
 
1062
    while ((!state_serv.err && !state_serv.done) || (!state_cli.err && !state_cli.done))
 
1063
    {
 
1064
#ifdef PJ_SYMBIAN
 
1065
        pj_symbianos_poll(-1, 1000);
 
1066
#else
 
1067
        pj_time_val delay = {0, 100};
 
1068
        pj_ioqueue_poll(ioqueue, &delay);
 
1069
        pj_timer_heap_poll(timer, &delay);
 
1070
#endif
 
1071
    }
 
1072
 
 
1073
    if (state_serv.err || state_cli.err) {
 
1074
        if (state_cli.err != PJ_SUCCESS)
 
1075
            status = state_cli.err;
 
1076
        else
 
1077
            status = state_serv.err;
 
1078
 
 
1079
        goto on_return;
 
1080
    }
 
1081
 
 
1082
    PJ_LOG(3, ("", "...Done!"));
 
1083
 
 
1084
on_return:
 
1085
    if (asock_serv)
 
1086
        pj_activesock_close(asock_serv);
 
1087
    if (ssock_cli && !state_cli.err && !state_cli.done)
 
1088
        pj_ssl_sock_close(ssock_cli);
 
1089
    if (timer)
 
1090
        pj_timer_heap_destroy(timer);
 
1091
    if (ioqueue)
 
1092
        pj_ioqueue_destroy(ioqueue);
 
1093
    if (pool)
 
1094
        pj_pool_release(pool);
 
1095
 
 
1096
    return status;
 
1097
}
 
1098
 
 
1099
 
 
1100
/* Test will perform multiple clients trying to connect to single server.
 
1101
 * Once SSL connection established, echo test will be performed.
 
1102
 */
 
1103
static int perf_test(unsigned clients, unsigned ms_handshake_timeout)
 
1104
{
 
1105
    pj_pool_t *pool = NULL;
 
1106
    pj_ioqueue_t *ioqueue = NULL;
 
1107
    pj_timer_heap_t *timer = NULL;
 
1108
    pj_ssl_sock_t *ssock_serv = NULL;
 
1109
    pj_ssl_sock_t **ssock_cli = NULL;
 
1110
    pj_ssl_sock_param param;
 
1111
    struct test_state state_serv = { 0 };
 
1112
    struct test_state *state_cli = NULL;
 
1113
    pj_sockaddr addr, listen_addr;
 
1114
    pj_ssl_cert_t *cert = NULL;
 
1115
    pj_status_t status;
 
1116
    unsigned i, cli_err = 0;
 
1117
    pj_size_t tot_sent = 0, tot_recv = 0;
 
1118
    pj_time_val start;
 
1119
 
 
1120
    pool = pj_pool_create(mem, "ssl_perf", 256, 256, NULL);
 
1121
 
 
1122
    status = pj_ioqueue_create(pool, PJ_IOQUEUE_MAX_HANDLES, &ioqueue);
 
1123
    if (status != PJ_SUCCESS) {
 
1124
        goto on_return;
 
1125
    }
 
1126
 
 
1127
    status = pj_timer_heap_create(pool, PJ_IOQUEUE_MAX_HANDLES, &timer);
 
1128
    if (status != PJ_SUCCESS) {
 
1129
        goto on_return;
 
1130
    }
 
1131
 
 
1132
    /* Set cert */
 
1133
    {
 
1134
        pj_str_t tmp1, tmp2, tmp3, tmp4;
 
1135
 
 
1136
        status = pj_ssl_cert_load_from_files(pool, 
 
1137
                                             pj_strset2(&tmp1, (char*)CERT_CA_FILE), 
 
1138
                                             pj_strset2(&tmp2, (char*)CERT_FILE), 
 
1139
                                             pj_strset2(&tmp3, (char*)CERT_PRIVKEY_FILE), 
 
1140
                                             pj_strset2(&tmp4, (char*)CERT_PRIVKEY_PASS), 
 
1141
                                             &cert);
 
1142
        if (status != PJ_SUCCESS) {
 
1143
            goto on_return;
 
1144
        }
 
1145
    }
 
1146
 
 
1147
    pj_ssl_sock_param_default(&param);
 
1148
    param.cb.on_accept_complete = &ssl_on_accept_complete;
 
1149
    param.cb.on_connect_complete = &ssl_on_connect_complete;
 
1150
    param.cb.on_data_read = &ssl_on_data_read;
 
1151
    param.cb.on_data_sent = &ssl_on_data_sent;
 
1152
    param.ioqueue = ioqueue;
 
1153
    param.timer_heap = timer;
 
1154
    param.timeout.sec = 0;
 
1155
    param.timeout.msec = ms_handshake_timeout;
 
1156
    pj_time_val_normalize(&param.timeout);
 
1157
 
 
1158
    /* Init default bind address */
 
1159
    {
 
1160
        pj_str_t tmp_st;
 
1161
        pj_sockaddr_init(PJ_AF_INET, &addr, pj_strset2(&tmp_st, "127.0.0.1"), 0);
 
1162
    }
 
1163
 
 
1164
    /* SERVER */
 
1165
    param.user_data = &state_serv;
 
1166
 
 
1167
    state_serv.pool = pool;
 
1168
    state_serv.echo = PJ_TRUE;
 
1169
    state_serv.is_server = PJ_TRUE;
 
1170
 
 
1171
    status = pj_ssl_sock_create(pool, &param, &ssock_serv);
 
1172
    if (status != PJ_SUCCESS) {
 
1173
        goto on_return;
 
1174
    }
 
1175
 
 
1176
    status = pj_ssl_sock_set_certificate(ssock_serv, pool, cert);
 
1177
    if (status != PJ_SUCCESS) {
 
1178
        goto on_return;
 
1179
    }
 
1180
 
 
1181
    status = pj_ssl_sock_start_accept(ssock_serv, pool, &addr, pj_sockaddr_get_len(&addr));
 
1182
    if (status != PJ_SUCCESS) {
 
1183
        goto on_return;
 
1184
    }
 
1185
 
 
1186
    /* Get listening address for clients to connect to */
 
1187
    {
 
1188
        pj_ssl_sock_info info;
 
1189
        char buf[64];
 
1190
 
 
1191
        pj_ssl_sock_get_info(ssock_serv, &info);
 
1192
        pj_sockaddr_cp(&listen_addr, &info.local_addr);
 
1193
 
 
1194
        pj_sockaddr_print((pj_sockaddr_t*)&listen_addr, buf, sizeof(buf), 1);
 
1195
        PJ_LOG(3, ("", "...Listener ready at %s", buf));
 
1196
    }
 
1197
 
 
1198
 
 
1199
    /* CLIENTS */
 
1200
    clients_num = clients;
 
1201
    param.timeout.sec = 0;
 
1202
    param.timeout.msec = 0;
 
1203
 
 
1204
    /* Init random seed */
 
1205
    {
 
1206
        pj_time_val now;
 
1207
 
 
1208
        pj_gettimeofday(&now);
 
1209
        pj_srand((unsigned)now.sec);
 
1210
    }
 
1211
 
 
1212
    /* Allocate SSL socket pointers and test state */
 
1213
    ssock_cli = (pj_ssl_sock_t**)pj_pool_calloc(pool, clients, sizeof(pj_ssl_sock_t*));
 
1214
    state_cli = (struct test_state*)pj_pool_calloc(pool, clients, sizeof(struct test_state));
 
1215
 
 
1216
    /* Get start timestamp */
 
1217
    pj_gettimeofday(&start);
 
1218
 
 
1219
    /* Setup clients */
 
1220
    for (i = 0; i < clients; ++i) {
 
1221
        param.user_data = &state_cli[i];
 
1222
 
 
1223
        state_cli[i].pool = pool;
 
1224
        state_cli[i].check_echo = PJ_TRUE;
 
1225
        state_cli[i].send_str_len = (pj_rand() % 5 + 1) * 1024 + pj_rand() % 1024;
 
1226
        state_cli[i].send_str = (char*)pj_pool_alloc(pool, state_cli[i].send_str_len);
 
1227
        {
 
1228
            unsigned j;
 
1229
            for (j = 0; j < state_cli[i].send_str_len; ++j)
 
1230
                state_cli[i].send_str[j] = (char)(pj_rand() % 256);
 
1231
        }
 
1232
 
 
1233
        status = pj_ssl_sock_create(pool, &param, &ssock_cli[i]);
 
1234
        if (status != PJ_SUCCESS) {
 
1235
            app_perror("...ERROR pj_ssl_sock_create()", status);
 
1236
            cli_err++;
 
1237
            clients_num--;
 
1238
            continue;
 
1239
        }
 
1240
 
 
1241
        status = pj_ssl_sock_start_connect(ssock_cli[i], pool, &addr, &listen_addr, pj_sockaddr_get_len(&addr));
 
1242
        if (status == PJ_SUCCESS) {
 
1243
            ssl_on_connect_complete(ssock_cli[i], PJ_SUCCESS);
 
1244
        } else if (status == PJ_EPENDING) {
 
1245
            status = PJ_SUCCESS;
 
1246
        } else {
 
1247
            app_perror("...ERROR pj_ssl_sock_create()", status);
 
1248
            pj_ssl_sock_close(ssock_cli[i]);
 
1249
            ssock_cli[i] = NULL;
 
1250
            clients_num--;
 
1251
            cli_err++;
 
1252
            continue;
 
1253
        }
 
1254
 
 
1255
        /* Give chance to server to accept this client */
 
1256
        {
 
1257
            unsigned n = 5;
 
1258
 
 
1259
#ifdef PJ_SYMBIAN
 
1260
            while(n && pj_symbianos_poll(-1, 1000))
 
1261
                n--;
 
1262
#else
 
1263
            pj_time_val delay = {0, 100};
 
1264
            while(n && pj_ioqueue_poll(ioqueue, &delay) > 0)
 
1265
                n--;
 
1266
#endif
 
1267
        }
 
1268
    }
 
1269
 
 
1270
    /* Wait until everything has been sent/received or error */
 
1271
    while (clients_num)
 
1272
    {
 
1273
#ifdef PJ_SYMBIAN
 
1274
        pj_symbianos_poll(-1, 1000);
 
1275
#else
 
1276
        pj_time_val delay = {0, 100};
 
1277
        pj_ioqueue_poll(ioqueue, &delay);
 
1278
        pj_timer_heap_poll(timer, &delay);
 
1279
#endif
 
1280
    }
 
1281
 
 
1282
    /* Clean up sockets */
 
1283
    {
 
1284
        pj_time_val delay = {0, 500};
 
1285
        while (pj_ioqueue_poll(ioqueue, &delay) > 0);
 
1286
    }
 
1287
 
 
1288
    if (state_serv.err != PJ_SUCCESS) {
 
1289
        status = state_serv.err;
 
1290
        goto on_return;
 
1291
    }
 
1292
 
 
1293
    PJ_LOG(3, ("", "...Done!"));
 
1294
 
 
1295
    /* SSL setup and data transfer duration */
 
1296
    {
 
1297
        pj_time_val stop;
 
1298
        
 
1299
        pj_gettimeofday(&stop);
 
1300
        PJ_TIME_VAL_SUB(stop, start);
 
1301
 
 
1302
        PJ_LOG(3, ("", ".....Setup & data transfer duration: %d.%03ds", stop.sec, stop.msec));
 
1303
    }
 
1304
 
 
1305
    /* Check clients status */
 
1306
    for (i = 0; i < clients; ++i) {
 
1307
        if (state_cli[i].err != PJ_SUCCESS)
 
1308
            cli_err++;
 
1309
 
 
1310
        tot_sent += state_cli[1].sent;
 
1311
        tot_recv += state_cli[1].recv;
 
1312
    }
 
1313
 
 
1314
    PJ_LOG(3, ("", ".....Clients: %d (%d errors)", clients, cli_err));
 
1315
    PJ_LOG(3, ("", ".....Total sent/recv: %d/%d bytes", tot_sent, tot_recv));
 
1316
 
 
1317
on_return:
 
1318
    if (ssock_serv) 
 
1319
        pj_ssl_sock_close(ssock_serv);
 
1320
 
 
1321
    for (i = 0; i < clients; ++i) {
 
1322
        if (ssock_cli[i] && !state_cli[i].err && !state_cli[i].done)
 
1323
            pj_ssl_sock_close(ssock_cli[i]);
 
1324
    }
 
1325
    if (ioqueue)
 
1326
        pj_ioqueue_destroy(ioqueue);
 
1327
    if (pool)
 
1328
        pj_pool_release(pool);
 
1329
 
 
1330
    return status;
 
1331
}
 
1332
 
 
1333
#if 0 && (!defined(PJ_SYMBIAN) || PJ_SYMBIAN==0)
 
1334
pj_status_t pj_ssl_sock_ossl_test_send_buf(pj_pool_t *pool);
 
1335
static int ossl_test_send_buf()
 
1336
{
 
1337
    pj_pool_t *pool;
 
1338
    pj_status_t status;
 
1339
 
 
1340
    pool = pj_pool_create(mem, "send_buf", 256, 256, NULL);
 
1341
    status = pj_ssl_sock_ossl_test_send_buf(pool);
 
1342
    pj_pool_release(pool);
 
1343
    return status;
 
1344
}
 
1345
#else
 
1346
static int ossl_test_send_buf()
 
1347
{
 
1348
    return 0;
 
1349
}
 
1350
#endif
 
1351
 
 
1352
int ssl_sock_test(void)
 
1353
{
 
1354
    int ret;
 
1355
 
 
1356
    PJ_LOG(3,("", "..test ossl send buf"));
 
1357
    ret = ossl_test_send_buf();
 
1358
    if (ret != 0)
 
1359
        return ret;
 
1360
 
 
1361
    PJ_LOG(3,("", "..get cipher list test"));
 
1362
    ret = get_cipher_list();
 
1363
    if (ret != 0)
 
1364
        return ret;
 
1365
 
 
1366
    PJ_LOG(3,("", "..https client test"));
 
1367
    ret = https_client_test(30000);
 
1368
    // Ignore test result as internet connection may not be available.
 
1369
    //if (ret != 0)
 
1370
        //return ret;
 
1371
 
 
1372
#ifndef PJ_SYMBIAN
 
1373
   
 
1374
    /* On Symbian platforms, SSL socket is implemented using CSecureSocket, 
 
1375
     * and it hasn't supported server mode, so exclude the following tests,
 
1376
     * which require SSL server, for now.
 
1377
     */
 
1378
 
 
1379
    PJ_LOG(3,("", "..echo test w/ TLSv1 and PJ_TLS_RSA_WITH_DES_CBC_SHA cipher"));
 
1380
    ret = echo_test(PJ_SSL_SOCK_PROTO_TLS1, PJ_SSL_SOCK_PROTO_TLS1, 
 
1381
                    PJ_TLS_RSA_WITH_DES_CBC_SHA, PJ_TLS_RSA_WITH_DES_CBC_SHA, 
 
1382
                    PJ_FALSE, PJ_FALSE);
 
1383
    if (ret != 0)
 
1384
        return ret;
 
1385
 
 
1386
    PJ_LOG(3,("", "..echo test w/ SSLv23 and PJ_TLS_RSA_WITH_AES_256_CBC_SHA cipher"));
 
1387
    ret = echo_test(PJ_SSL_SOCK_PROTO_SSL23, PJ_SSL_SOCK_PROTO_SSL23, 
 
1388
                    PJ_TLS_RSA_WITH_AES_256_CBC_SHA, PJ_TLS_RSA_WITH_AES_256_CBC_SHA,
 
1389
                    PJ_FALSE, PJ_FALSE);
 
1390
    if (ret != 0)
 
1391
        return ret;
 
1392
 
 
1393
    PJ_LOG(3,("", "..echo test w/ incompatible proto"));
 
1394
    ret = echo_test(PJ_SSL_SOCK_PROTO_TLS1, PJ_SSL_SOCK_PROTO_SSL3, 
 
1395
                    PJ_TLS_RSA_WITH_DES_CBC_SHA, PJ_TLS_RSA_WITH_DES_CBC_SHA,
 
1396
                    PJ_FALSE, PJ_FALSE);
 
1397
    if (ret == 0)
 
1398
        return PJ_EBUG;
 
1399
 
 
1400
    PJ_LOG(3,("", "..echo test w/ incompatible ciphers"));
 
1401
    ret = echo_test(PJ_SSL_SOCK_PROTO_DEFAULT, PJ_SSL_SOCK_PROTO_DEFAULT, 
 
1402
                    PJ_TLS_RSA_WITH_DES_CBC_SHA, PJ_TLS_RSA_WITH_AES_256_CBC_SHA,
 
1403
                    PJ_FALSE, PJ_FALSE);
 
1404
    if (ret == 0)
 
1405
        return PJ_EBUG;
 
1406
 
 
1407
    PJ_LOG(3,("", "..echo test w/ client cert required but not provided"));
 
1408
    ret = echo_test(PJ_SSL_SOCK_PROTO_DEFAULT, PJ_SSL_SOCK_PROTO_DEFAULT, 
 
1409
                    PJ_TLS_RSA_WITH_AES_256_CBC_SHA, PJ_TLS_RSA_WITH_AES_256_CBC_SHA,
 
1410
                    PJ_TRUE, PJ_FALSE);
 
1411
    if (ret == 0)
 
1412
        return PJ_EBUG;
 
1413
 
 
1414
    PJ_LOG(3,("", "..echo test w/ client cert required and provided"));
 
1415
    ret = echo_test(PJ_SSL_SOCK_PROTO_DEFAULT, PJ_SSL_SOCK_PROTO_DEFAULT, 
 
1416
                    PJ_TLS_RSA_WITH_AES_256_CBC_SHA, PJ_TLS_RSA_WITH_AES_256_CBC_SHA,
 
1417
                    PJ_TRUE, PJ_TRUE);
 
1418
    if (ret != 0)
 
1419
        return ret;
 
1420
 
 
1421
    PJ_LOG(3,("", "..performance test"));
 
1422
    ret = perf_test(PJ_IOQUEUE_MAX_HANDLES/2 - 1, 0);
 
1423
    if (ret != 0)
 
1424
        return ret;
 
1425
 
 
1426
    PJ_LOG(3,("", "..client non-SSL (handshake timeout 5 secs)"));
 
1427
    ret = client_non_ssl(5000);
 
1428
    /* PJ_TIMEDOUT won't be returned as accepted socket is deleted silently */
 
1429
    if (ret != 0)
 
1430
        return ret;
 
1431
 
 
1432
#endif
 
1433
 
 
1434
    PJ_LOG(3,("", "..server non-SSL (handshake timeout 5 secs)"));
 
1435
    ret = server_non_ssl(5000);
 
1436
    if (ret != PJ_ETIMEDOUT)
 
1437
        return ret;
 
1438
 
 
1439
    return 0;
 
1440
}
 
1441
 
 
1442
#else   /* INCLUDE_SSLSOCK_TEST */
 
1443
/* To prevent warning about "translation unit is empty"
 
1444
 * when this test is disabled. 
 
1445
 */
 
1446
int dummy_ssl_sock_test;
 
1447
#endif  /* INCLUDE_SSLSOCK_TEST */
 
1448