/* * Class: com_oracle_libuv_handles_UDPHandle * Method: _send6 * Signature: (JLjava/nio/ByteBuffer;[BIIILjava/lang/String;)I */ JNIEXPORT jint JNICALL Java_com_oracle_libuv_handles_UDPHandle__1send6 (JNIEnv *env, jobject that, jlong udp, jobject buffer, jbyteArray data, jint offset, jint length, jint port, jstring host, jobject context) { assert(udp); uv_udp_t* handle = reinterpret_cast<uv_udp_t*>(udp); const char* h = env->GetStringUTFChars(host, 0); sockaddr_in6 addr = uv_ip6_addr(h, port); jbyte* base = (jbyte*) env->GetPrimitiveArrayCritical(data, NULL); OOME(env, base); uv_buf_t buf; buf.base = reinterpret_cast<char*>(base + offset); buf.len = length; uv_udp_send_t* req = new uv_udp_send_t(); req->handle = handle; ContextHolder* req_data = new ContextHolder(env, context); req->data = req_data; int r = uv_udp_send6(req, handle, &buf, 1, addr, _send_cb); env->ReleasePrimitiveArrayCritical(data, base, 0); if (r) { delete req_data; delete req; ThrowException(env, handle->loop, "uv_udp_send6", h); } env->ReleaseStringUTFChars(host, h); return r; }
int32_t uv_udp_handle_t::write_handle(request_udp_write_t& request) { int result; uv_buf_t uv_buf; write_uv_request_t* uv_request = get_write_cached_request(); uv_request->m_source = request.m_source; uv_request->m_session = request.m_session; uv_request->m_length = request.m_length; if (request.m_length > 0) { uv_request->m_string = request.m_string; uv_buf.len = request.m_length; uv_buf.base = (char*)request.m_string; } else { uv_request->m_buffer = request.m_buffer; uv_buf.len = buffer_data_length(request.m_buffer); uv_buf.base = buffer_data_ptr(request.m_buffer); } if (!request.m_ipv6) { result = uv_udp_send(&uv_request->m_write_req, (uv_udp_t*)m_handle, &uv_buf, 1, uv_ip4_addr(REQUEST_SPARE_PTR(request), request.m_port), on_write); } else { result = uv_udp_send6(&uv_request->m_write_req, (uv_udp_t*)m_handle, &uv_buf, 1, uv_ip6_addr(REQUEST_SPARE_PTR(request), request.m_port), on_write); } if (result == 0) return UV_OK; put_write_cached_request(uv_request); return singleton_ref(network_t).last_error(); /* write error occurs */ }
static int luv_udp__send(lua_State* L, int family) { uv_buf_t buf; uv_udp_t* handle = (uv_udp_t*)luv_checkudata(L, 1, "udp"); size_t len; const char* chunk = luaL_checklstring(L, 2, &len); luv_udp_ref_t *ref; uv_udp_send_t* req = (uv_udp_send_t*)malloc(sizeof(uv_udp_send_t)); int port = luaL_checkint(L, 3); const char* host = luaL_checkstring(L, 4); struct sockaddr_in dest; struct sockaddr_in6 dest6; int rc; /* Store a reference to the callback */ lua_pushvalue(L, 5); ref = malloc(sizeof(*ref)); ref->ref = luaL_ref(L, LUA_REGISTRYINDEX); req->data = ref; luv_handle_ref(L, handle->data, 1); /* Store the chunk * TODO: this is probably unsafe, should investigate */ buf = uv_buf_init((char*)chunk, len); switch(family) { case AF_INET: dest = uv_ip4_addr(host, port); rc = uv_udp_send(req, handle, &buf, 1, dest, luv_on_udp_send); break; case AF_INET6: dest6 = uv_ip6_addr(host, port); rc = uv_udp_send6(req, handle, &buf, 1, dest6, luv_on_udp_send); break; default: assert(0 && "unexpected family type"); abort(); } if (rc) { uv_err_t err = uv_last_error(luv_get_loop(L)); return luaL_error(L, "udp_send: %s", uv_strerror(err)); } return 0; }
int UDPSocket::send(const char* data, std::size_t len, const Address& peerAddress, int /* flags */) { TraceS(this) << "Send: " << len << ": " << peerAddress << endl; assert(Thread::currentID() == tid()); // assert(len <= net::MAX_UDP_PACKET_SIZE); if (_peer.valid() && _peer != peerAddress) { ErrorS(this) << "Peer not authorized: " << peerAddress << endl; return -1; } if (!peerAddress.valid()) { ErrorS(this) << "Peer not valid: " << peerAddress << endl; return -1; } int r; auto sr = new internal::SendRequest; sr->buf = uv_buf_init((char*)data, len); // TODO: memcpy data? r = uv_udp_send(&sr->req, ptr<uv_udp_t>(), &sr->buf, 1, peerAddress.addr(), UDPSocket::afterSend); #if 0 switch (peerAddress.af()) { case AF_INET: r = uv_udp_send(&sr->req, ptr<uv_udp_t>(), &sr->buf, 1, peerAddress.addr(), UDPSocket::afterSend); break; case AF_INET6: r = uv_udp_send6(&sr->req, ptr<uv_udp_t>(), &sr->buf, 1, *reinterpret_cast<const sockaddr_in6*>(peerAddress.addr()), UDPSocket::afterSend); break; default: throw std::runtime_error("Unexpected address family"); } #endif if (r) { ErrorS(this) << "Send failed: " << uv_err_name(r) << endl; setUVError("Invalid UDP socket", r); } // R is -1 on error, otherwise return len return r ? r : len; }
static PyObject * UDP_func_send(UDP *self, PyObject *args) { int r, dest_port, address_type; char *dest_ip; uv_buf_t buf; Py_buffer *view; PyObject *callback = Py_None; uv_udp_send_t *wr = NULL; udp_send_data_t *req_data = NULL; RAISE_IF_HANDLE_NOT_INITIALIZED(self, NULL); RAISE_IF_HANDLE_CLOSED(self, PyExc_HandleClosedError, NULL); view = PyMem_Malloc(sizeof *view); if (!view) { PyErr_NoMemory(); return NULL; } #ifdef PYUV_PYTHON3 if (!PyArg_ParseTuple(args, "(si)y*|O:send", &dest_ip, &dest_port, view, &callback)) { #else if (!PyArg_ParseTuple(args, "(si)s*|O:send", &dest_ip, &dest_port, view, &callback)) { #endif return NULL; } if (callback != Py_None && !PyCallable_Check(callback)) { PyErr_SetString(PyExc_TypeError, "a callable or None is required"); goto error1; } if (dest_port < 0 || dest_port > 65535) { PyErr_SetString(PyExc_ValueError, "port must be between 0 and 65535"); goto error1; } if (pyuv_guess_ip_family(dest_ip, &address_type)) { PyErr_SetString(PyExc_ValueError, "invalid IP address"); goto error1; } Py_INCREF(callback); wr = PyMem_Malloc(sizeof *wr); if (!wr) { PyErr_NoMemory(); goto error2; } req_data = PyMem_Malloc(sizeof *req_data); if (!req_data) { PyErr_NoMemory(); goto error2; } buf = uv_buf_init(view->buf, view->len); req_data->callback = callback; req_data->view_count = 1; req_data->views = view; wr->data = (void *)req_data; if (address_type == AF_INET) { r = uv_udp_send(wr, (uv_udp_t *)UV_HANDLE(self), &buf, 1, uv_ip4_addr(dest_ip, dest_port), (uv_udp_send_cb)on_udp_send); } else { r = uv_udp_send6(wr, (uv_udp_t *)UV_HANDLE(self), &buf, 1, uv_ip6_addr(dest_ip, dest_port), (uv_udp_send_cb)on_udp_send); } if (r != 0) { RAISE_UV_EXCEPTION(UV_HANDLE_LOOP(self), PyExc_UDPError); goto error2; } /* Increase refcount so that object is not removed before the callback is called */ Py_INCREF(self); Py_RETURN_NONE; error2: Py_DECREF(callback); PyMem_Free(req_data); PyMem_Free(wr); error1: PyBuffer_Release(view); PyMem_Free(view); return NULL; } static PyObject * UDP_func_sendlines(UDP *self, PyObject *args) { int i, r, buf_count, dest_port, address_type; char *dest_ip; PyObject *callback, *seq; Py_buffer *views; uv_buf_t *bufs; uv_udp_send_t *wr = NULL; udp_send_data_t *req_data = NULL; callback = Py_None; RAISE_IF_HANDLE_NOT_INITIALIZED(self, NULL); RAISE_IF_HANDLE_CLOSED(self, PyExc_HandleClosedError, NULL); if (!PyArg_ParseTuple(args, "(si)O|O:sendlines", &dest_ip, &dest_port, &seq, &callback)) { return NULL; } if (callback != Py_None && !PyCallable_Check(callback)) { PyErr_SetString(PyExc_TypeError, "a callable or None is required"); return NULL; } if (dest_port < 0 || dest_port > 65535) { PyErr_SetString(PyExc_ValueError, "port must be between 0 and 65535"); return NULL; } if (pyuv_guess_ip_family(dest_ip, &address_type)) { PyErr_SetString(PyExc_ValueError, "invalid IP address"); return NULL; } r = pyseq2uvbuf(seq, &views, &bufs, &buf_count); if (r != 0) { /* error is already set */ return NULL; } Py_INCREF(callback); wr = PyMem_Malloc(sizeof *wr); if (!wr) { PyErr_NoMemory(); goto error; } req_data = PyMem_Malloc(sizeof *req_data); if (!req_data) { PyErr_NoMemory(); goto error; } req_data->callback = callback; req_data->view_count = buf_count; req_data->views = views; wr->data = (void *)req_data; if (address_type == AF_INET) { r = uv_udp_send(wr, (uv_udp_t *)UV_HANDLE(self), bufs, buf_count, uv_ip4_addr(dest_ip, dest_port), (uv_udp_send_cb)on_udp_send); } else { r = uv_udp_send6(wr, (uv_udp_t *)UV_HANDLE(self), bufs, buf_count, uv_ip6_addr(dest_ip, dest_port), (uv_udp_send_cb)on_udp_send); } /* uv_write copies the uv_buf_t structures, so we can free them now */ PyMem_Free(bufs); bufs = NULL; if (r != 0) { RAISE_UV_EXCEPTION(UV_HANDLE_LOOP(self), PyExc_UDPError); goto error; } /* Increase refcount so that object is not removed before the callback is called */ Py_INCREF(self); Py_RETURN_NONE; error: Py_DECREF(callback); for (i = 0; i < buf_count; i++) { PyBuffer_Release(&views[i]); } PyMem_Free(views); PyMem_Free(bufs); PyMem_Free(req_data); PyMem_Free(wr); return NULL; }
static PyObject * UDP_func_sendlines(UDP *self, PyObject *args) { int i, r, buf_count, dest_port, address_type; char *dest_ip; PyObject *callback, *seq; uv_buf_t *bufs; uv_udp_send_t *wr = NULL; udp_send_data_t *req_data = NULL; callback = Py_None; RAISE_IF_HANDLE_CLOSED(self, PyExc_HandleClosedError, NULL); if (!PyArg_ParseTuple(args, "(si)O|O:sendlines", &dest_ip, &dest_port, &seq, &callback)) { return NULL; } if (callback != Py_None && !PyCallable_Check(callback)) { PyErr_SetString(PyExc_TypeError, "a callable or None is required"); return NULL; } if (dest_port < 0 || dest_port > 65535) { PyErr_SetString(PyExc_ValueError, "port must be between 0 and 65535"); return NULL; } if (pyuv_guess_ip_family(dest_ip, &address_type)) { PyErr_SetString(PyExc_ValueError, "invalid IP address"); return NULL; } Py_INCREF(callback); r = pyseq2uvbuf(seq, &bufs, &buf_count); if (r != 0) { /* error is already set */ goto error; } if (buf_count == 0) { PyErr_SetString(PyExc_ValueError, "Sequence is empty"); goto error; } wr = (uv_udp_send_t *)PyMem_Malloc(sizeof(uv_udp_send_t)); if (!wr) { PyErr_NoMemory(); goto error; } req_data = (udp_send_data_t*) PyMem_Malloc(sizeof(udp_send_data_t)); if (!req_data) { PyErr_NoMemory(); goto error; } req_data->callback = callback; req_data->buf_count = buf_count; req_data->data.bufs = bufs; wr->data = (void *)req_data; if (address_type == AF_INET) { r = uv_udp_send(wr, (uv_udp_t *)UV_HANDLE(self), bufs, buf_count, uv_ip4_addr(dest_ip, dest_port), (uv_udp_send_cb)on_udp_send); } else { r = uv_udp_send6(wr, (uv_udp_t *)UV_HANDLE(self), bufs, buf_count, uv_ip6_addr(dest_ip, dest_port), (uv_udp_send_cb)on_udp_send); } if (r != 0) { RAISE_UV_EXCEPTION(UV_HANDLE_LOOP(self), PyExc_UDPError); goto error; } Py_RETURN_NONE; error: Py_DECREF(callback); if (bufs) { for (i = 0; i < buf_count; i++) { PyMem_Free(bufs[i].base); } PyMem_Free(bufs); } if (req_data) { PyMem_Free(req_data); } if (wr) { PyMem_Free(wr); } return NULL; }
static PyObject * UDP_func_send(UDP *self, PyObject *args) { int r, dest_port, address_type; char *dest_ip; uv_buf_t buf; Py_buffer pbuf; PyObject *callback; uv_udp_send_t *wr = NULL; udp_send_data_t *req_data = NULL; callback = Py_None; RAISE_IF_HANDLE_CLOSED(self, PyExc_HandleClosedError, NULL); if (!PyArg_ParseTuple(args, "(si)s*|O:send", &dest_ip, &dest_port, &pbuf, &callback)) { return NULL; } if (callback != Py_None && !PyCallable_Check(callback)) { PyBuffer_Release(&pbuf); PyErr_SetString(PyExc_TypeError, "a callable or None is required"); return NULL; } if (dest_port < 0 || dest_port > 65535) { PyErr_SetString(PyExc_ValueError, "port must be between 0 and 65535"); return NULL; } if (pyuv_guess_ip_family(dest_ip, &address_type)) { PyErr_SetString(PyExc_ValueError, "invalid IP address"); return NULL; } Py_INCREF(callback); wr = (uv_udp_send_t *)PyMem_Malloc(sizeof(uv_udp_send_t)); if (!wr) { PyErr_NoMemory(); goto error; } req_data = (udp_send_data_t*) PyMem_Malloc(sizeof(udp_send_data_t)); if (!req_data) { PyErr_NoMemory(); goto error; } buf = uv_buf_init(pbuf.buf, pbuf.len); req_data->callback = callback; req_data->buf_count = 1; req_data->data.view = pbuf; wr->data = (void *)req_data; if (address_type == AF_INET) { r = uv_udp_send(wr, (uv_udp_t *)UV_HANDLE(self), &buf, 1, uv_ip4_addr(dest_ip, dest_port), (uv_udp_send_cb)on_udp_send); } else { r = uv_udp_send6(wr, (uv_udp_t *)UV_HANDLE(self), &buf, 1, uv_ip6_addr(dest_ip, dest_port), (uv_udp_send_cb)on_udp_send); } if (r != 0) { RAISE_UV_EXCEPTION(UV_HANDLE_LOOP(self), PyExc_UDPError); goto error; } Py_RETURN_NONE; error: PyBuffer_Release(&pbuf); Py_DECREF(callback); if (req_data) { PyMem_Free(req_data); } if (wr) { PyMem_Free(wr); } return NULL; }
extern "C" int rust_uv_udp_send6(uv_udp_send_t* req, uv_udp_t* handle, uv_buf_t* buf_in, int buf_cnt, sockaddr_in6* addr_ptr, uv_udp_send_cb cb) { return uv_udp_send6(req, handle, buf_in, buf_cnt, *addr_ptr, cb); }