int udp_start(struct tundev_context *ctx, uv_loop_t *loop) { int rc; ctx->network_buffer = malloc(ctx->tun->mtu + PRIMITIVE_BYTES); uv_udp_init(loop, &ctx->inet_udp); ctx->inet_udp_fd = create_socket(SOCK_DGRAM, mode == xTUN_SERVER ? 1 : 0); if ((rc = uv_udp_open(&ctx->inet_udp, ctx->inet_udp_fd))) { logger_log(LOG_ERR, "udp open error: %s", uv_strerror(rc)); exit(1); } #ifdef ANDROID rc = protect_socket(ctx->inet_udp_fd); logger_log(rc ? LOG_INFO : LOG_ERR, "Protect socket %s", rc ? "successful" : "failed"); #endif if (mode == xTUN_SERVER) { rc = uv_udp_bind(&ctx->inet_udp, &ctx->tun->addr, UV_UDP_REUSEADDR); if (rc) { logger_stderr("udp bind error: %s", uv_strerror(rc)); exit(1); } } return uv_udp_recv_start(&ctx->inet_udp, inet_alloc_cb, inet_recv_cb); }
int udprelay_start(uv_loop_t *loop, struct server_context *server) { int rc; if (server->dest_addr->sa_family == AF_INET6) { addrlen = IPV6_HEADER_LEN; } uv_udp_init(loop, &server->udp); if ((rc = uv_udp_open(&server->udp, server->udp_fd))) { logger_stderr("udp open error: %s", uv_strerror(rc)); return 1; } rc = uv_udp_bind(&server->udp, server->local_addr, UV_UDP_REUSEADDR); if (rc) { logger_stderr("bind error: %s", uv_strerror(rc)); return 1; } uv_udp_recv_start(&server->udp, client_alloc_cb, client_recv_cb); return 0; }
int udprelay_start(uv_loop_t *loop, struct server_context *server) { int rc, yes = 1; if (setsockopt(server->udp_fd, SOL_IP, IP_TRANSPARENT, &yes, sizeof(int))) { logger_stderr("setsockopt IP_TRANSPARENT error: %s", strerror(errno)); } if (setsockopt(server->udp_fd, IPPROTO_IP, IP_RECVORIGDSTADDR, &yes, sizeof(int))) { logger_stderr("setsockopt IP_RECVORIGDSTADDR error: %s", strerror(errno)); } uv_udp_init(loop, &server->udp); if ((rc = uv_udp_open(&server->udp, server->udp_fd))) { logger_stderr("udp open error: %s", uv_strerror(rc)); return 1; } if ((rc = uv_udp_bind(&server->udp, server->local_addr, UV_UDP_REUSEADDR))) { logger_stderr("udp bind error: %s", uv_strerror(rc)); return 1; } uv_poll_init_socket(loop, &server->watcher, server->udp_fd); uv_poll_start(&server->watcher, UV_READABLE, poll_cb); return 0; }
static int luv_udp_open(lua_State* L) { uv_udp_t* handle = luv_check_udp(L, 1); uv_os_sock_t sock = luaL_checkinteger(L, 2); int ret = uv_udp_open(handle, sock); if (ret < 0) return luv_error(L, ret); lua_pushinteger(L, ret); return 1; }
//Initialize the Linux-specific part of the context. All is related to //libmnl/netfilter struct neat_ctx *nt_linux_init_ctx(struct neat_ctx *ctx) { //TODO: Consider allocator function if ((ctx->mnl_rcv_buf = calloc(1, MNL_SOCKET_BUFFER_SIZE)) == NULL) { nt_log(ctx, NEAT_LOG_ERROR, "Failed to allocate netlink buffer", __func__); return NULL; } //Configure netlink and start requesting addresses if ((ctx->mnl_sock = mnl_socket_open(NETLINK_ROUTE)) == NULL) { nt_log(ctx, NEAT_LOG_ERROR, "Failed to allocate netlink socket", __func__); return NULL; } if (mnl_socket_bind(ctx->mnl_sock, (1 << (RTNLGRP_IPV4_IFADDR - 1)) | (1 << (RTNLGRP_IPV6_IFADDR - 1)), 0)) { nt_log(ctx, NEAT_LOG_ERROR, "Failed to bind netlink socket", __func__); return NULL; } //We need to build a list of all available source addresses as soon as //possible. It is started here if (neat_linux_request_addrs(ctx->mnl_sock) <= 0) { nt_log(ctx, NEAT_LOG_ERROR, "Failed to request addresses", __func__); return NULL; } //Add socket to event loop if (uv_udp_init(ctx->loop, &(ctx->uv_nl_handle))) { nt_log(ctx, NEAT_LOG_ERROR, "Failed to initialize uv UDP handle", __func__); return NULL; } //TODO: We could use offsetof, but libuv has a pointer so ... ctx->uv_nl_handle.data = ctx; if (uv_udp_open(&(ctx->uv_nl_handle), mnl_socket_get_fd(ctx->mnl_sock))) { nt_log(ctx, NEAT_LOG_ERROR, "Could not add netlink socket to uv", __func__); return NULL; } if (uv_udp_recv_start(&(ctx->uv_nl_handle), neat_linux_nl_alloc, nt_linux_nl_recv)) { nt_log(ctx, NEAT_LOG_ERROR, "Could not start receiving netlink packets", __func__); return NULL; } ctx->cleanup = nt_linux_cleanup; #ifdef MPTCP_SUPPORT linux_read_sys_mptcp_enabled(ctx); #endif // MPTCP_SUPPORT //Configure netlink socket, add to event loop and start dumping return ctx; }
static int lluv_udp_open(lua_State *L){ lluv_handle_t *handle = lluv_check_udp(L, 1, LLUV_FLAG_OPEN); uv_os_sock_t sock = (uv_os_sock_t)lutil_checkint64(L, 2); int err = uv_udp_open(LLUV_H(handle, uv_udp_t), sock); if(err < 0){ return lluv_fail(L, handle->flags, LLUV_ERR_UV, err, NULL); } lua_settop(L, 1); return 1; }
int udp_bindfd(uv_udp_t *handle, int fd) { if (!handle) { return kr_error(EINVAL); } int ret = uv_udp_open(handle, (uv_os_sock_t) fd); if (ret != 0) { return ret; } return udp_bind_finalize((uv_handle_t *)handle); }
//Initialize the Linux-specific part of the context. All is related to //libmnl/netfilter struct neat_ctx *neat_linux_init_ctx(struct neat_ctx *nc) { //TODO: Consider allocator function if ((nc->mnl_rcv_buf = calloc(MNL_SOCKET_BUFFER_SIZE, 1)) == NULL) { fprintf(stderr, "Failed to allocate netlink buffer\n"); return NULL; } //Configure netlink and start requesting addresses if ((nc->mnl_sock = mnl_socket_open(NETLINK_ROUTE)) == NULL) { fprintf(stderr, "Failed to allocate netlink socket\n"); return NULL; } if (mnl_socket_bind(nc->mnl_sock, (1 << (RTNLGRP_IPV4_IFADDR - 1)) | (1 << (RTNLGRP_IPV6_IFADDR - 1)), 0)) { fprintf(stderr, "Failed to bind netlink socket\n"); return NULL; } //We need to build a list of all available source addresses as soon as //possible. It is started here if (neat_linux_request_addrs(nc->mnl_sock) <= 0) { fprintf(stderr, "Failed to request addresses\n"); return NULL; } //Add socket to event loop if (uv_udp_init(nc->loop, &(nc->uv_nl_handle))) { fprintf(stderr, "Failed to initialize uv UDP handle\n"); return NULL; } //TODO: We could use offsetof, but libuv has a pointer so ... nc->uv_nl_handle.data = nc; if (uv_udp_open(&(nc->uv_nl_handle), mnl_socket_get_fd(nc->mnl_sock))) { fprintf(stderr, "Could not add netlink socket to uv\n"); return NULL; } if (uv_udp_recv_start(&(nc->uv_nl_handle), neat_linux_nl_alloc, neat_linux_nl_recv)) { fprintf(stderr, "Could not start receiving netlink packets\n"); return NULL; } nc->cleanup = neat_linux_cleanup; //Configure netlink socket, add to event loop and start dumping return nc; }
int uv_accept(uv_stream_t* server, uv_stream_t* client) { uv_stream_t* streamServer; uv_stream_t* streamClient; int saved_errno; int status; /* TODO document this */ assert(server->loop == client->loop); saved_errno = errno; status = -1; streamServer = (uv_stream_t*)server; streamClient = (uv_stream_t*)client; if (streamServer->accepted_fd < 0) { uv__set_sys_error(server->loop, EAGAIN); goto out; } switch (streamClient->type) { case UV_NAMED_PIPE: case UV_TCP: if (uv__stream_open(streamClient, streamServer->accepted_fd, UV_STREAM_READABLE | UV_STREAM_WRITABLE)) { /* TODO handle error */ close(streamServer->accepted_fd); streamServer->accepted_fd = -1; goto out; } break; case UV_UDP: if (uv_udp_open((uv_udp_t*) client, streamServer->accepted_fd)) { close(streamServer->accepted_fd); streamServer->accepted_fd = -1; goto out; } break; default: assert(0); } uv__io_start(streamServer->loop, &streamServer->io_watcher, UV__POLLIN); streamServer->accepted_fd = -1; status = 0; out: errno = saved_errno; return status; }
static PyObject * UDP_func_open(UDP *self, PyObject *args) { long fd; RAISE_IF_HANDLE_NOT_INITIALIZED(self, NULL); RAISE_IF_HANDLE_CLOSED(self, PyExc_HandleClosedError, NULL); if (!PyArg_ParseTuple(args, "l:open", &fd)) { return NULL; } uv_udp_open((uv_udp_t *)UV_HANDLE(self), (uv_os_sock_t)fd); Py_RETURN_NONE; }
/* * Class: com_oracle_libuv_handles_UDPHandle * Method: _new * Signature: (JJ)J */ JNIEXPORT jlong JNICALL Java_com_oracle_libuv_handles_UDPHandle__1new__JJ (JNIEnv *env, jclass cls, jlong loop, jlong socket) { assert(loop); uv_loop_t* lp = reinterpret_cast<uv_loop_t*>(loop); uv_udp_t* udp = new uv_udp_t(); int r = uv_udp_init(lp, udp); if (r) { ThrowException(env, udp->loop, "uv_udp_init"); return (jlong) NULL; } r = uv_udp_open(udp, (uv_os_sock_t) socket); if (r) { ThrowException(env, udp->loop, "uv_udp_open"); delete udp; return (jlong) NULL; } udp->data = new UDPCallbacks(); return reinterpret_cast<jlong>(udp); }
static void server_recv_cb(uv_udp_t *handle, ssize_t nread, const uv_buf_t *buf, const struct sockaddr *addr, unsigned flags) { if (nread > 0) { struct client_context *client = handle->data; reset_timer(client); int mlen = nread - PRIMITIVE_BYTES; uint8_t *m = (uint8_t *)buf->base; int rc = crypto_decrypt(m, (uint8_t *)buf->base, nread); if (rc) { logger_log(LOG_ERR, "invalid udp packet"); goto err; } /* * * xsocks UDP Response * +------+----------+----------+----------+ * | ATYP | DST.ADDR | DST.PORT | DATA | * +------+----------+----------+----------+ * | 1 | Variable | 2 | Variable | * +------+----------+----------+----------+ * */ union { struct sockaddr addr; struct sockaddr_in addr4; struct sockaddr_in6 addr6; } dest_addr; if (m[0] == ATYP_IPV4) { dest_addr.addr4.sin_family = AF_INET; memcpy(&dest_addr.addr4.sin_addr, m + 1, 4); memcpy(&dest_addr.addr4.sin_port, m + 5, 2); } else { dest_addr.addr6.sin6_family = AF_INET6; memcpy(&dest_addr.addr6.sin6_addr, m + 1, 16); memcpy(&dest_addr.addr6.sin6_port, m + 17, 2); } int addrlen = m[0] == ATYP_IPV4 ? IPV4_HEADER_LEN : IPV6_HEADER_LEN; memmove(m, m + addrlen, mlen - addrlen); mlen -= addrlen; if (!client->bind_server) { uv_os_sock_t sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP); if (sock < 0) { logger_stderr("socket error: %s\n", strerror(errno)); } int yes = 1; if (setsockopt(sock, SOL_IP, IP_TRANSPARENT, &yes, sizeof(int))) { logger_stderr("setsockop IP_TRANSPARENT error: %s)", strerror(errno)); } client->dest_handle = malloc(sizeof(uv_udp_t)); uv_udp_init(handle->loop, client->dest_handle); rc = uv_udp_open(client->dest_handle, sock); if (rc) { logger_stderr("udp open error: %s", uv_strerror(rc)); } rc = uv_udp_bind(client->dest_handle, &dest_addr.addr, UV_UDP_REUSEADDR); if (rc) { logger_stderr("udp server bind error: %s", uv_strerror(rc)); } client->bind_server = 1; } forward_to_client(client, m , mlen); } else { goto err; } return; err: free(buf->base); }