/* * This utility function creates receive data buffers and start * asynchronous recv() operations from the socket. It is called after * accept() or connect() operation complete. */ static pj_status_t tls_start_read(struct tls_transport *tls) { pj_pool_t *pool; pj_ssize_t size; pj_sockaddr_in *rem_addr; void *readbuf[1]; pj_status_t status; /* Init rdata */ pool = pjsip_endpt_create_pool(tls->base.endpt, "rtd%p", PJSIP_POOL_RDATA_LEN, PJSIP_POOL_RDATA_INC); if (!pool) { tls_perror(tls->base.obj_name, "Unable to create pool", PJ_ENOMEM); return PJ_ENOMEM; } tls->rdata.tp_info.pool = pool; tls->rdata.tp_info.transport = &tls->base; tls->rdata.tp_info.tp_data = tls; tls->rdata.tp_info.op_key.rdata = &tls->rdata; pj_ioqueue_op_key_init(&tls->rdata.tp_info.op_key.op_key, sizeof(pj_ioqueue_op_key_t)); tls->rdata.pkt_info.src_addr = tls->base.key.rem_addr; tls->rdata.pkt_info.src_addr_len = sizeof(pj_sockaddr_in); rem_addr = (pj_sockaddr_in*) &tls->base.key.rem_addr; pj_ansi_strcpy(tls->rdata.pkt_info.src_name, pj_inet_ntoa(rem_addr->sin_addr)); tls->rdata.pkt_info.src_port = pj_ntohs(rem_addr->sin_port); size = sizeof(tls->rdata.pkt_info.packet); readbuf[0] = tls->rdata.pkt_info.packet; status = pj_ssl_sock_start_read2(tls->ssock, tls->base.pool, size, readbuf, 0); if (status != PJ_SUCCESS && status != PJ_EPENDING) { PJ_LOG(4, (tls->base.obj_name, "pj_ssl_sock_start_read() error, status=%d", status)); return status; } return PJ_SUCCESS; }
static pj_bool_t ssl_on_accept_complete(pj_ssl_sock_t *ssock, pj_ssl_sock_t *newsock, const pj_sockaddr_t *src_addr, int src_addr_len) { struct test_state *parent_st = (struct test_state*) pj_ssl_sock_get_user_data(ssock); struct test_state *st; void *read_buf[1]; pj_ssl_sock_info info; char buf[64]; pj_status_t status; PJ_UNUSED_ARG(src_addr_len); /* Duplicate parent test state to newly accepted test state */ st = pj_pool_zalloc(parent_st->pool, sizeof(struct test_state)); *st = *parent_st; pj_ssl_sock_set_user_data(newsock, st); status = pj_ssl_sock_get_info(newsock, &info); if (status != PJ_SUCCESS) { app_perror("...ERROR pj_ssl_sock_get_info()", status); goto on_return; } pj_sockaddr_print(src_addr, buf, sizeof(buf), 1); PJ_LOG(3, ("", "...Accepted connection from %s", buf)); if (st->is_verbose) dump_ssl_info(&info); /* Start reading data */ read_buf[0] = st->read_buf; status = pj_ssl_sock_start_read2(newsock, st->pool, sizeof(st->read_buf), (void**)read_buf, 0); if (status != PJ_SUCCESS) { app_perror("...ERROR pj_ssl_sock_start_read2()", status); goto on_return; } /* Start sending data */ while (st->sent < st->send_str_len) { pj_ssize_t size; size = st->send_str_len - st->sent; status = pj_ssl_sock_send(newsock, (pj_ioqueue_op_key_t*)&st->send_key, st->send_str + st->sent, &size, 0); if (status != PJ_SUCCESS && status != PJ_EPENDING) { app_perror("...ERROR pj_ssl_sock_send()", status); goto on_return; } if (status == PJ_SUCCESS) st->sent += size; else break; } on_return: st->err = status; if (st->err != PJ_SUCCESS) { pj_ssl_sock_close(newsock); return PJ_FALSE; } return PJ_TRUE; }
static pj_bool_t ssl_on_connect_complete(pj_ssl_sock_t *ssock, pj_status_t status) { struct test_state *st = (struct test_state*) pj_ssl_sock_get_user_data(ssock); void *read_buf[1]; pj_ssl_sock_info info; char buf1[64], buf2[64]; if (status != PJ_SUCCESS) { app_perror("...ERROR ssl_on_connect_complete()", status); goto on_return; } status = pj_ssl_sock_get_info(ssock, &info); if (status != PJ_SUCCESS) { app_perror("...ERROR pj_ssl_sock_get_info()", status); goto on_return; } pj_sockaddr_print((pj_sockaddr_t*)&info.local_addr, buf1, sizeof(buf1), 1); pj_sockaddr_print((pj_sockaddr_t*)&info.remote_addr, buf2, sizeof(buf2), 1); PJ_LOG(3, ("", "...Connected %s -> %s!", buf1, buf2)); if (st->is_verbose) dump_ssl_info(&info); /* Start reading data */ read_buf[0] = st->read_buf; status = pj_ssl_sock_start_read2(ssock, st->pool, sizeof(st->read_buf), (void**)read_buf, 0); if (status != PJ_SUCCESS) { app_perror("...ERROR pj_ssl_sock_start_read2()", status); goto on_return; } /* Start sending data */ while (st->sent < st->send_str_len) { pj_ssize_t size; size = st->send_str_len - st->sent; status = pj_ssl_sock_send(ssock, (pj_ioqueue_op_key_t*)&st->send_key, st->send_str + st->sent, &size, 0); if (status != PJ_SUCCESS && status != PJ_EPENDING) { app_perror("...ERROR pj_ssl_sock_send()", status); goto on_return; } if (status == PJ_SUCCESS) st->sent += size; else break; } on_return: st->err = status; if (st->err != PJ_SUCCESS) { pj_ssl_sock_close(ssock); clients_num--; return PJ_FALSE; } return PJ_TRUE; }