void muta_connect(libmuta_processing_callback f, void *priv) { struct sockaddr_storage addr_storage; struct sockaddr *addr = NULL; uint32_t addrlen = 0; memset(&addr_storage, 0, sizeof(addr_storage)); addr = (struct sockaddr *)&addr_storage; addrlen = sizeof(addr_storage); pomp_addr_parse(LIBMUTA_IMAGE_SOCKET, addr, &addrlen); s_app.ctx = pomp_ctx_new(client_event_cb, f); s_app.loop = pomp_ctx_get_loop(s_app.ctx); client_start(addr, addrlen); s_app.stop = 0; s_app.priv = priv; s_app.process = f; while (!s_app.stop) { pomp_loop_wait_and_process(s_app.loop, -1); } if (s_app.ctx != NULL) { pomp_ctx_stop(s_app.ctx); pomp_ctx_destroy(s_app.ctx); } }
static void test_invalid_addr(void) { int res = 0; struct test_data data; struct sockaddr_in addr_in; struct sockaddr *addr = NULL; uint32_t addrlen = 0; struct pomp_ctx *ctx = NULL; memset(&data, 0, sizeof(data)); /* Setup test address (inexistent addr) */ memset(&addr_in, 0, sizeof(addr_in)); addr_in.sin_family = AF_INET; addr_in.sin_addr.s_addr = 0x01000001; addr_in.sin_port = htons(5656); addr = (struct sockaddr *)&addr_in; addrlen = sizeof(addr_in); /* Create context */ ctx = pomp_ctx_new(&test_event_cb_t, &data); CU_ASSERT_PTR_NOT_NULL_FATAL(ctx); /* Start as server */ res = pomp_ctx_listen(ctx, addr, addrlen); CU_ASSERT_EQUAL(res, 0); res = pomp_ctx_wait_and_process(ctx, 2500); CU_ASSERT_EQUAL(res, 0); res = pomp_ctx_stop(ctx); CU_ASSERT_EQUAL(res, 0); /* Start as client */ res = pomp_ctx_connect(ctx, addr, addrlen); CU_ASSERT_EQUAL(res, 0); res = pomp_ctx_wait_and_process(ctx, 2500); CU_ASSERT(res == 0 || res == -ETIMEDOUT); res = pomp_ctx_stop(ctx); CU_ASSERT_EQUAL(res, 0); /* Destroy context */ res = pomp_ctx_destroy(ctx); CU_ASSERT_EQUAL(res, 0); }
static int test_ipc_entry(pomp_event_cb_t cb, const struct sockaddr *addr, uint32_t addrlen, int client) { int res = 0; struct test_data data; struct pomp_ctx *ctx = NULL; struct pomp_loop *loop = NULL; struct pomp_timer *timer = NULL; memset(&data, 0, sizeof(data)); data.pid = getpid(); TEST_IPC_LOG("-> %s", __func__); /* Setup */ ctx = pomp_ctx_new(cb, &data); TEST_IPC_CHECK(&data, ctx != NULL); loop = pomp_ctx_get_loop(ctx); TEST_IPC_CHECK(&data, loop != NULL); timer = pomp_timer_new(loop, &test_ipc_timer_cb, &data); TEST_IPC_CHECK(&data, timer != NULL); res = pomp_timer_set(timer, 10 * 1000); TEST_IPC_CHECK(&data, res == 0); /* Start client/server */ if (client) res = pomp_ctx_connect(ctx, addr, addrlen); else res = pomp_ctx_listen(ctx, addr, addrlen); TEST_IPC_CHECK(&data, res == 0); /* Run loop */ while (!data.stop) pomp_loop_wait_and_process(loop, -1); /* Cleanup */ res = pomp_timer_destroy(timer); TEST_IPC_CHECK(&data, res == 0); res = pomp_ctx_stop(ctx); TEST_IPC_CHECK(&data, res == 0); res = pomp_ctx_destroy(ctx); TEST_IPC_CHECK(&data, res == 0); TEST_IPC_LOG("<-- %s", __func__); return data.status; }
static void test_ctx(const struct sockaddr *addr1, uint32_t addrlen1, const struct sockaddr *addr2, uint32_t addrlen2, int isdgram, int israw, int withsockcb, int withsendcb) { int res = 0; struct test_data data; struct pomp_loop *loop = NULL; struct pomp_conn *conn = NULL; struct pomp_msg *msg = NULL; int fd = -1; uint32_t i = 0, j = 0; struct pomp_buffer *buf = NULL; memset(&data, 0, sizeof(data)); data.isdgram = isdgram; data.israw = israw; data.srv.addr = addr1; data.srv.addrlen = addrlen1; data.cli.addr = addr2; data.cli.addrlen = addrlen2; msg = pomp_msg_new(); CU_ASSERT_PTR_NOT_NULL_FATAL(msg); /* Create context */ data.srv.ctx = pomp_ctx_new(&test_event_cb_t, &data); CU_ASSERT_PTR_NOT_NULL_FATAL(data.srv.ctx); if (israw) { res = pomp_ctx_set_raw(data.srv.ctx, &test_ctx_raw_cb); CU_ASSERT_EQUAL(res, 0); } if (withsockcb) { res = pomp_ctx_set_socket_cb(data.srv.ctx, &test_ctx_socket_cb); CU_ASSERT_EQUAL(res, 0); } if (withsendcb) { res = pomp_ctx_set_send_cb(data.srv.ctx, &test_ctx_send_cb); CU_ASSERT_EQUAL(res, 0); } /* Create context without callback */ data.cli.ctx = pomp_ctx_new(NULL, &data); CU_ASSERT_PTR_NOT_NULL_FATAL(data.cli.ctx); res = pomp_ctx_destroy(data.cli.ctx); CU_ASSERT_EQUAL(res, 0); /* Invalid create (NULL 3nd arg) */ data.cli.ctx = pomp_ctx_new_with_loop(NULL, &data, NULL); CU_ASSERT_PTR_NULL(data.cli.ctx); data.cli.ctx = pomp_ctx_new_with_loop(&test_event_cb_t, &data, NULL); CU_ASSERT_PTR_NULL(data.cli.ctx); /* Create 2nd context */ data.cli.ctx = pomp_ctx_new(&test_event_cb_t, &data); CU_ASSERT_PTR_NOT_NULL_FATAL(data.cli.ctx); if (israw) { res = pomp_ctx_set_raw(data.cli.ctx, &test_ctx_raw_cb); CU_ASSERT_EQUAL(res, 0); } if (withsockcb) { res = pomp_ctx_set_socket_cb(data.cli.ctx, &test_ctx_socket_cb); CU_ASSERT_EQUAL(res, 0); } if (withsendcb) { res = pomp_ctx_set_send_cb(data.cli.ctx, &test_ctx_send_cb); CU_ASSERT_EQUAL(res, 0); } if (!isdgram) { /* Invalid start server (NULL param) */ res = pomp_ctx_listen(NULL, addr1, addrlen1); CU_ASSERT_EQUAL(res, -EINVAL); res = pomp_ctx_listen(data.srv.ctx, NULL, addrlen1); CU_ASSERT_EQUAL(res, -EINVAL); /* Start as server 1st context */ res = pomp_ctx_listen(data.srv.ctx, addr1, addrlen1); CU_ASSERT_EQUAL(res, 0); /* Invalid start server (busy) */ res = pomp_ctx_listen(data.srv.ctx, addr1, addrlen1); CU_ASSERT_EQUAL(res, -EBUSY); } else { /* Invalid bind (NULL param) */ res = pomp_ctx_bind(NULL, addr1, addrlen1); CU_ASSERT_EQUAL(res, -EINVAL); res = pomp_ctx_bind(data.srv.ctx, NULL, addrlen1); CU_ASSERT_EQUAL(res, -EINVAL); /* Bind 1st context */ res = pomp_ctx_bind(data.srv.ctx, addr1, addrlen1); CU_ASSERT_EQUAL(res, 0); /* Invalid bind (busy) */ res = pomp_ctx_bind(data.srv.ctx, addr1, addrlen1); CU_ASSERT_EQUAL(res, -EBUSY); } if (!isdgram) { /* Invalid start client (NULL param) */ res = pomp_ctx_connect(NULL, addr2, addrlen2); CU_ASSERT_EQUAL(res, -EINVAL); res = pomp_ctx_connect(data.cli.ctx, NULL, addrlen2); CU_ASSERT_EQUAL(res, -EINVAL); /* Start as client 2nd context */ res = pomp_ctx_connect(data.cli.ctx, addr2, addrlen2); CU_ASSERT_EQUAL(res, 0); /* Invalid start client (busy) */ res = pomp_ctx_connect(data.cli.ctx, addr2, addrlen2); CU_ASSERT_EQUAL(res, -EBUSY); } else { /* Invalid bind (NULL param) */ res = pomp_ctx_bind(NULL, addr2, addrlen2); CU_ASSERT_EQUAL(res, -EINVAL); res = pomp_ctx_bind(data.cli.ctx, NULL, addrlen2); CU_ASSERT_EQUAL(res, -EINVAL); /* Bind 2nd context */ res = pomp_ctx_bind(data.cli.ctx, addr2, addrlen2); CU_ASSERT_EQUAL(res, 0); /* Invalid bind (busy) */ res = pomp_ctx_bind(data.cli.ctx, addr2, addrlen2); CU_ASSERT_EQUAL(res, -EBUSY); } /* Invalid set raw */ res = pomp_ctx_set_raw(NULL, &test_ctx_raw_cb); CU_ASSERT_EQUAL(res, -EINVAL); res = pomp_ctx_set_raw(data.srv.ctx, NULL); CU_ASSERT_EQUAL(res, -EINVAL); res = pomp_ctx_set_raw(data.srv.ctx, &test_ctx_raw_cb); CU_ASSERT_EQUAL(res, -EBUSY); /* Invalid set socket cb */ res = pomp_ctx_set_socket_cb(NULL, &test_ctx_socket_cb); CU_ASSERT_EQUAL(res, -EINVAL); res = pomp_ctx_set_socket_cb(data.srv.ctx, NULL); CU_ASSERT_EQUAL(res, -EINVAL); res = pomp_ctx_set_socket_cb(data.srv.ctx, &test_ctx_socket_cb); CU_ASSERT_EQUAL(res, -EBUSY); /* Invalid set send cb */ res = pomp_ctx_set_send_cb(NULL, &test_ctx_send_cb); CU_ASSERT_EQUAL(res, -EINVAL); res = pomp_ctx_set_send_cb(data.srv.ctx, NULL); CU_ASSERT_EQUAL(res, -EINVAL); res = pomp_ctx_set_send_cb(data.srv.ctx, &test_ctx_send_cb); CU_ASSERT_EQUAL(res, -EBUSY); /* Invalid get loop (NULL param) */ loop = pomp_ctx_get_loop(NULL); CU_ASSERT_PTR_NULL(loop); /* Invalid get fd (NULL param) */ fd = pomp_ctx_get_fd(NULL); CU_ASSERT_EQUAL(fd, -EINVAL); /* Get loop and fd */ loop = pomp_ctx_get_loop(data.srv.ctx); CU_ASSERT_PTR_NOT_NULL(loop); fd = pomp_ctx_get_fd(data.srv.ctx); #ifdef POMP_HAVE_LOOP_EPOLL CU_ASSERT_TRUE(fd >= 0); #else CU_ASSERT_EQUAL(fd, -ENOSYS); #endif /* Invalid process fd (NULL param) */ res = pomp_ctx_process_fd(NULL); CU_ASSERT_EQUAL(res, -EINVAL); /* Keepalive settings */ if (!isdgram) { /* TODO: check that it actually does something */ res = pomp_ctx_setup_keepalive(data.srv.ctx, 0, 0, 0, 0); CU_ASSERT_EQUAL(res, 0); res = pomp_ctx_setup_keepalive(data.srv.ctx, 1, 5, 2, 1); CU_ASSERT_EQUAL(res, 0); res = pomp_ctx_setup_keepalive(NULL, 0, 0, 0, 0); CU_ASSERT_EQUAL(res, -EINVAL); } /* Run contexts (they shall connect each other) */ run_ctx(data.srv.ctx, data.cli.ctx, 100); if (!isdgram) { CU_ASSERT_EQUAL(data.connection, 2); /* Get remote connections */ conn = pomp_ctx_get_next_conn(data.srv.ctx, NULL); CU_ASSERT_PTR_NOT_NULL(conn); conn = pomp_ctx_get_next_conn(data.srv.ctx, conn); CU_ASSERT_PTR_NULL(conn); conn = pomp_ctx_get_conn(data.cli.ctx); CU_ASSERT_PTR_NOT_NULL(conn); /* Invalid get remote connections */ conn = pomp_ctx_get_next_conn(data.cli.ctx, NULL); CU_ASSERT_PTR_NULL(conn); conn = pomp_ctx_get_conn(data.srv.ctx); CU_ASSERT_PTR_NULL(conn); conn = pomp_ctx_get_next_conn(NULL, NULL); CU_ASSERT_PTR_NULL(conn); conn = pomp_ctx_get_conn(NULL); CU_ASSERT_PTR_NULL(conn); } /* Exchange some message */ if (!isdgram) { if (!israw) { res = pomp_ctx_send(data.srv.ctx, 1, "%s", "hello1->2"); CU_ASSERT_EQUAL(res, 0); res = pomp_ctx_send(data.cli.ctx, 1, "%s", "hello2->1"); CU_ASSERT_EQUAL(res, 0); /* Invalid send (NULL param) */ res = pomp_ctx_send(NULL, 1, "%s", "hello1->2"); CU_ASSERT_EQUAL(res, -EINVAL); res = pomp_ctx_send_msg(data.srv.ctx, NULL); CU_ASSERT_EQUAL(res, -EINVAL); /* Invalid send (bad format) */ res = pomp_ctx_send(data.srv.ctx, 1, "%o", 1); CU_ASSERT_EQUAL(res, -EINVAL); res = pomp_conn_send(pomp_ctx_get_conn(data.cli.ctx), 1, "%o", 1); CU_ASSERT_EQUAL(res, -EINVAL); /* Invalid send to (bad type) */ res = pomp_ctx_send_msg_to(data.cli.ctx, msg, addr1, addrlen1); CU_ASSERT_EQUAL(res, -EINVAL); } else { buf = pomp_buffer_new(32); CU_ASSERT_PTR_NOT_NULL_FATAL(buf); memcpy(buf->data, "Hello World !!!", 15); buf->len = 15; res = pomp_ctx_send_raw_buf(data.srv.ctx, buf); data.datasent += 15; CU_ASSERT_EQUAL(res, 0); res = pomp_ctx_send_raw_buf(data.cli.ctx, buf); data.datasent += 15; CU_ASSERT_EQUAL(res, 0); /* Invalid send (NULL param) */ res = pomp_ctx_send_raw_buf(NULL, buf); CU_ASSERT_EQUAL(res, -EINVAL); res = pomp_ctx_send_raw_buf(data.srv.ctx, NULL); CU_ASSERT_EQUAL(res, -EINVAL); pomp_buffer_unref(buf); buf = NULL; } } else { if (!israw) { res = pomp_msg_clear(msg); CU_ASSERT_EQUAL(res, 0); res = pomp_msg_write(msg, 1, "%s", "hello1->2"); CU_ASSERT_EQUAL(res, 0); res = pomp_ctx_send_msg_to(data.srv.ctx, msg, addr2, addrlen2); CU_ASSERT_EQUAL(res, 0); res = pomp_msg_clear(msg); CU_ASSERT_EQUAL(res, 0); res = pomp_msg_write(msg, 1, "%s", "hello2->1"); CU_ASSERT_EQUAL(res, 0); res = pomp_ctx_send_msg_to(data.cli.ctx, msg, addr1, addrlen1); CU_ASSERT_EQUAL(res, 0); /* Invalid send (not connected) */ res = pomp_ctx_send_msg(data.cli.ctx, msg); CU_ASSERT_EQUAL(res, -ENOTCONN); /* Invalid send to (NULL param) */ res = pomp_ctx_send_msg_to(NULL, msg, addr1, addrlen1); CU_ASSERT_EQUAL(res, -EINVAL); res = pomp_ctx_send_msg_to(data.cli.ctx, NULL, addr1, addrlen1); CU_ASSERT_EQUAL(res, -EINVAL); res = pomp_ctx_send_msg_to(data.cli.ctx, msg, NULL, addrlen1); CU_ASSERT_EQUAL(res, -EINVAL); } else { buf = pomp_buffer_new(32); CU_ASSERT_PTR_NOT_NULL_FATAL(buf); memcpy(buf->data, "Hello World !!!", 15); buf->len = 15; res = pomp_ctx_send_raw_buf_to(data.srv.ctx, buf, addr2, addrlen2); CU_ASSERT_EQUAL(res, 0); data.datasent += 15; res = pomp_ctx_send_raw_buf_to(data.cli.ctx, buf, addr1, addrlen1); CU_ASSERT_EQUAL(res, 0); data.datasent += 15; /* Invalid send (not connected) */ res = pomp_ctx_send_raw_buf(data.cli.ctx, buf); CU_ASSERT_EQUAL(res, -ENOTCONN); /* Invalid send to (NULL param) */ res = pomp_ctx_send_raw_buf_to(NULL, buf, addr1, addrlen1); CU_ASSERT_EQUAL(res, -EINVAL); res = pomp_ctx_send_raw_buf_to(data.cli.ctx, NULL, addr1, addrlen1); CU_ASSERT_EQUAL(res, -EINVAL); res = pomp_ctx_send_raw_buf_to(data.cli.ctx, buf, NULL, addrlen1); CU_ASSERT_EQUAL(res, -EINVAL); pomp_buffer_unref(buf); buf = NULL; } } /* Check no send callback directly called by the sending function. */ CU_ASSERT_EQUAL(data.sendcount, 0); /* Run contexts (they shall have answered each other) */ run_ctx(data.srv.ctx, data.cli.ctx, 100); if (!israw) { CU_ASSERT_EQUAL(data.msg, 4); if (withsendcb) CU_ASSERT_EQUAL(data.sendcount, 4); } else { if (data.isdgram) CU_ASSERT_EQUAL(data.buf, 2); CU_ASSERT_EQUAL(data.dataread, data.datasent); if (withsendcb) CU_ASSERT_EQUAL(data.sendcount, 2); } /* Dummy run */ res = pomp_ctx_wait_and_process(data.srv.ctx, 100); CU_ASSERT_EQUAL(res, -ETIMEDOUT); res = pomp_ctx_wait_and_process(NULL, 100); CU_ASSERT_EQUAL(res, -EINVAL); /* Wakeup */ res = pomp_ctx_wakeup(data.srv.ctx); CU_ASSERT_EQUAL(res, 0); res = pomp_ctx_wait_and_process(data.srv.ctx, 100); CU_ASSERT_EQUAL(res, 0); /* Invalid wakeup (NULL param) */ res = pomp_ctx_wakeup(NULL); CU_ASSERT_EQUAL(res, -EINVAL); /* Overflow server by writing on client side without running loop */ if (!isdgram) { for (i = 0; i < 1024; i++) { if (buf == NULL) buf = pomp_buffer_new(1024); CU_ASSERT_PTR_NOT_NULL_FATAL(buf); for (j = 0; j < 1024; j++) buf->data[j] = rand() % 255; buf->len = 1024; if (!israw) { res = pomp_ctx_send(data.cli.ctx, 3, "%p%u", buf->data, 1024); CU_ASSERT_EQUAL(res, 0); } else { res = pomp_ctx_send_raw_buf(data.cli.ctx, buf); CU_ASSERT_EQUAL(res, 0); } if (buf->refcount > 1) { pomp_buffer_unref(buf); buf = NULL; } } if (buf != NULL) { pomp_buffer_unref(buf); buf = NULL; } /* Run contexts (to unlock writes) */ run_ctx(data.srv.ctx, data.cli.ctx, 100); if (!israw) CU_ASSERT_EQUAL(data.msg, 4 + 1024); } /* Recursive send */ if (withsendcb) { /* reset counts */ data.buf = 0; data.msg = 0; data.sendcount = 0; data.datasent = 0; data.dataread = 0; /* Enable recursive send. */ data.srv.recurs_send_enabled = 1; send_msg(&data, &data.srv, &data.cli, "srv_to_cli"); /* Check no send callback directly called by the sending function. */ CU_ASSERT_EQUAL(data.sendcount, 0); run_ctx(data.srv.ctx, data.cli.ctx, 100); if (!israw) { CU_ASSERT_EQUAL(data.msg, 2); CU_ASSERT_EQUAL(data.sendcount, 2); } else { if (data.isdgram) CU_ASSERT_EQUAL(data.buf, 2); CU_ASSERT_EQUAL(data.dataread, data.datasent); CU_ASSERT_EQUAL(data.sendcount, 2); } /* Check client recursive send during server disconnection */ data.cli.recurs_send_enabled = 1; send_msg(&data, &data.cli, &data.srv, "cli_to_srv"); } /* Disconnect client from server */ if (!isdgram) { if (withsendcb) { /* Check recursive write during disconnection */ data.srv.recurs_send_enabled = 1; data.isdisconnecting = 1; } res = pomp_conn_disconnect(pomp_ctx_get_next_conn(data.srv.ctx, NULL)); CU_ASSERT_EQUAL(res, 0); /* Check recursive send callback by disconnection */ if (withsendcb) CU_ASSERT_EQUAL(data.sendcount, 2); } /* Run contexts (they shall disconnect each other) */ run_ctx(data.srv.ctx, data.cli.ctx, 100); pomp_ctx_process_fd(data.cli.ctx); if (!isdgram) { CU_ASSERT_EQUAL(data.disconnection, 2); if (!israw) { /* Invalid send (client not connected) */ res = pomp_ctx_send(data.cli.ctx, 1, "%s", "hello2->1"); CU_ASSERT_EQUAL(res, -ENOTCONN); } else { /* TODO */ } } /* Invalid destroy (NULL param) */ res = pomp_ctx_destroy(NULL); CU_ASSERT_EQUAL(res, -EINVAL); /* Invalid destroy (busy) */ res = pomp_ctx_destroy(data.srv.ctx); CU_ASSERT_EQUAL(res, -EBUSY); /* Stop server */ res = pomp_ctx_stop(data.srv.ctx); CU_ASSERT_EQUAL(res, 0); /* Stop client */ res = pomp_ctx_stop(data.cli.ctx); CU_ASSERT_EQUAL(res, 0); /* Invalid stop (NULL param) */ res = pomp_ctx_stop(NULL); CU_ASSERT_EQUAL(res, -EINVAL); /* Stop when already done */ res = pomp_ctx_stop(data.srv.ctx); CU_ASSERT_EQUAL(res, 0); /* Destroy contexts */ res = pomp_ctx_destroy(data.srv.ctx); CU_ASSERT_EQUAL(res, 0); res = pomp_ctx_destroy(data.cli.ctx); CU_ASSERT_EQUAL(res, 0); res = pomp_msg_destroy(msg); CU_ASSERT_EQUAL(res, 0); }
static void test_local_addr(void) { int res = 0; struct sockaddr_in addr_in; struct pomp_ctx *ctx = NULL; const struct sockaddr *addr = NULL; uint32_t addrlen = 0; /* Create context */ ctx = pomp_ctx_new(&test_event_cb_t, NULL); CU_ASSERT_PTR_NOT_NULL_FATAL(ctx); /* Start as server with known port */ memset(&addr_in, 0, sizeof(addr_in)); addr_in.sin_family = AF_INET; addr_in.sin_addr.s_addr = htonl(INADDR_LOOPBACK); addr_in.sin_port = htons(5656); res = pomp_ctx_listen(ctx, (const struct sockaddr *)&addr_in, sizeof(addr_in)); CU_ASSERT_EQUAL(res, 0); /* Get local address */ addr = pomp_ctx_get_local_addr(ctx, &addrlen); CU_ASSERT_PTR_NOT_NULL(addr); CU_ASSERT_EQUAL(addrlen, sizeof(addr_in)); CU_ASSERT_EQUAL(memcmp(addr, &addr_in, sizeof(addr_in)), 0); /* Stop context */ res = pomp_ctx_stop(ctx); CU_ASSERT_EQUAL(res, 0); /* Start as server with dynamic port */ memset(&addr_in, 0, sizeof(addr_in)); addr_in.sin_family = AF_INET; addr_in.sin_addr.s_addr = htonl(INADDR_LOOPBACK); addr_in.sin_port = 0; res = pomp_ctx_listen(ctx, (const struct sockaddr *)&addr_in, sizeof(addr_in)); CU_ASSERT_EQUAL(res, 0); /* Get local address */ addr = pomp_ctx_get_local_addr(ctx, &addrlen); CU_ASSERT_PTR_NOT_NULL(addr); CU_ASSERT_EQUAL(addrlen, sizeof(addr_in)); CU_ASSERT_NOT_EQUAL(((const struct sockaddr_in *)addr)->sin_port, 0); /* Stop context */ res = pomp_ctx_stop(ctx); CU_ASSERT_EQUAL(res, 0); /* Start as dgram with known port */ memset(&addr_in, 0, sizeof(addr_in)); addr_in.sin_family = AF_INET; addr_in.sin_addr.s_addr = htonl(INADDR_LOOPBACK); addr_in.sin_port = htons(5656); res = pomp_ctx_bind(ctx, (const struct sockaddr *)&addr_in, sizeof(addr_in)); CU_ASSERT_EQUAL(res, 0); /* Get local address */ addr = pomp_ctx_get_local_addr(ctx, &addrlen); CU_ASSERT_PTR_NOT_NULL(addr); CU_ASSERT_EQUAL(addrlen, sizeof(addr_in)); CU_ASSERT_EQUAL(memcmp(addr, &addr_in, sizeof(addr_in)), 0); /* Stop context */ res = pomp_ctx_stop(ctx); CU_ASSERT_EQUAL(res, 0); /* Start as dgram with dynamic port */ memset(&addr_in, 0, sizeof(addr_in)); addr_in.sin_family = AF_INET; addr_in.sin_addr.s_addr = htonl(INADDR_LOOPBACK); addr_in.sin_port = 0; res = pomp_ctx_bind(ctx, (const struct sockaddr *)&addr_in, sizeof(addr_in)); CU_ASSERT_EQUAL(res, 0); /* Get local address */ addr = pomp_ctx_get_local_addr(ctx, &addrlen); CU_ASSERT_PTR_NOT_NULL(addr); CU_ASSERT_EQUAL(addrlen, sizeof(addr_in)); CU_ASSERT_NOT_EQUAL(((const struct sockaddr_in *)addr)->sin_port, 0); /* Stop context */ res = pomp_ctx_stop(ctx); CU_ASSERT_EQUAL(res, 0); /* Invalid get local addr */ addr = pomp_ctx_get_local_addr(NULL, &addrlen); CU_ASSERT_PTR_NULL(addr); addr = pomp_ctx_get_local_addr(ctx, NULL); CU_ASSERT_PTR_NULL(addr); res = pomp_ctx_connect(ctx, (const struct sockaddr *)&addr_in, sizeof(addr_in)); CU_ASSERT_EQUAL(res, 0); addr = pomp_ctx_get_local_addr(ctx, &addrlen); CU_ASSERT_PTR_NULL(addr); res = pomp_ctx_stop(ctx); CU_ASSERT_EQUAL(res, 0); /* Free context */ res = pomp_ctx_destroy(ctx); CU_ASSERT_EQUAL(res, 0); }