Fix address aliasing in sendmmsg0

Motivation:

When epoll datagram channel invokes sendmmsg0, _all_ of the messages go
on the wire with the address of the _last_ packet in the list.

Modifications:

An array of addresses equal to the length of the messages is allocated
on the stack to hold the address for each msg_hdr.msg_name.

Result:

Each message goes on the wire with the correct address.
This commit is contained in:
earthling 2016-05-10 21:20:28 -07:00 committed by Norman Maurer
parent 453b958988
commit 0e6695e4b6

View File

@ -232,24 +232,24 @@ static jint netty_epoll_native_epollCtlDel0(JNIEnv* env, jclass clazz, jint efd,
static jint netty_epoll_native_sendmmsg0(JNIEnv* env, jclass clazz, jint fd, jobjectArray packets, jint offset, jint len) {
struct mmsghdr msg[len];
struct sockaddr_storage addr[len];
int i;
memset(msg, 0, sizeof(msg));
for (i = 0; i < len; i++) {
struct sockaddr_storage addr;
jobject packet = (*env)->GetObjectArrayElement(env, packets, i + offset);
jbyteArray address = (jbyteArray) (*env)->GetObjectField(env, packet, packetAddrFieldId);
jint scopeId = (*env)->GetIntField(env, packet, packetScopeIdFieldId);
jint port = (*env)->GetIntField(env, packet, packetPortFieldId);
if (netty_unix_socket_initSockaddr(env, address, scopeId, port, &addr) == -1) {
if (netty_unix_socket_initSockaddr(env, address, scopeId, port, &addr[i]) == -1) {
return -1;
}
msg[i].msg_hdr.msg_name = &addr;
msg[i].msg_hdr.msg_namelen = sizeof(addr);
msg[i].msg_hdr.msg_name = &addr[i];
msg[i].msg_hdr.msg_namelen = sizeof(addr[i]);
msg[i].msg_hdr.msg_iov = (struct iovec*) (intptr_t) (*env)->GetLongField(env, packet, packetMemoryAddressFieldId);
msg[i].msg_hdr.msg_iovlen = (*env)->GetIntField(env, packet, packetCountFieldId);;