@@ -4085,12 +4085,12 @@ fn netSendOne(
40854085 flags : u32 ,
40864086) net.Socket.SendError ! void {
40874087 var addr : PosixAddress = undefined ;
4088- var iovec : posix.iovec_const = .{ . base = @constCast (message .data_ptr ), . len = message . data_len } ;
4088+ const iovecs : [] const posix.iovec_const = @ptrCast (message .data ) ;
40894089 const msg : posix.msghdr_const = .{
4090- .name = & addr .any ,
4091- .namelen = addressToPosix (message .address , & addr ),
4092- .iov = ( & iovec )[0 .. 1] ,
4093- .iovlen = 1 ,
4090+ .name = if ( message . address ) & addr .any else null ,
4091+ .namelen = if (message .address ) | a | addressToPosix ( a , & addr ) else 0 ,
4092+ .iov = iovecs . ptr ,
4093+ .iovlen = @intCast ( iovecs . len ) ,
40944094 // OS returns EINVAL if this pointer is invalid even if controllen is zero.
40954095 .control = if (message .control .len == 0 ) null else @constCast (message .control .ptr ),
40964096 .controllen = @intCast (message .control .len ),
@@ -4127,13 +4127,13 @@ fn netSendOne(
41274127 else = > | err | return windows .unexpectedWSAError (err ),
41284128 }
41294129 } else {
4130- message .data_len = @intCast (rc );
4130+ message .bytes_sent = @intCast (rc );
41314131 return ;
41324132 }
41334133 }
41344134 switch (posix .errno (rc )) {
41354135 .SUCCESS = > {
4136- message .data_len = @intCast (rc );
4136+ message .bytes_sent = @intCast (rc );
41374137 return ;
41384138 },
41394139 .INTR = > continue ,
@@ -4171,21 +4171,19 @@ fn netSendMany(
41714171) net.Socket.SendError ! usize {
41724172 var msg_buffer : [64 ]std.os.linux.mmsghdr = undefined ;
41734173 var addr_buffer : [msg_buffer .len ]PosixAddress = undefined ;
4174- var iovecs_buffer : [msg_buffer .len ]posix.iovec = undefined ;
41754174 const min_len : usize = @min (messages .len , msg_buffer .len );
41764175 const clamped_messages = messages [0.. min_len ];
41774176 const clamped_msgs = (& msg_buffer )[0.. min_len ];
41784177 const clamped_addrs = (& addr_buffer )[0.. min_len ];
4179- const clamped_iovecs = (& iovecs_buffer )[0.. min_len ];
41804178
4181- for (clamped_messages , clamped_msgs , clamped_addrs , clamped_iovecs ) | * message , * msg , * addr , * iovec | {
4182- iovec .* = .{ . base = @constCast (message .data_ptr ), . len = message . data_len } ;
4179+ for (clamped_messages , clamped_msgs , clamped_addrs ) | * message , * msg , * addr | {
4180+ const iovecs : [] posix.iovec = @ptrCast ( @ constCast (message .data )) ;
41834181 msg .* = .{
41844182 .hdr = .{
4185- .name = & addr .any ,
4186- .namelen = addressToPosix (message .address , addr ),
4187- .iov = iovec [0 .. 1] ,
4188- .iovlen = 1 ,
4183+ .name = if ( message . address == null ) null else & addr .any ,
4184+ .namelen = if (message .address ) | a | addressToPosix ( a , addr ) else 0 ,
4185+ .iov = iovecs . ptr ,
4186+ .iovlen = @intCast ( iovecs . len ) ,
41894187 .control = @constCast (message .control .ptr ),
41904188 .controllen = message .control .len ,
41914189 .flags = 0 ,
@@ -4201,7 +4199,7 @@ fn netSendMany(
42014199 .SUCCESS = > {
42024200 const n : usize = @intCast (rc );
42034201 for (clamped_messages [0.. n ], clamped_msgs [0.. n ]) | * message , * msg | {
4204- message .data_len = msg .len ;
4202+ message .bytes_sent = msg .len ;
42054203 }
42064204 return n ;
42074205 },
@@ -4236,7 +4234,6 @@ fn netReceivePosix(
42364234 userdata : ? * anyopaque ,
42374235 handle : net.Socket.Handle ,
42384236 message_buffer : []net.IncomingMessage ,
4239- data_buffer : []u8 ,
42404237 flags : net.ReceiveFlags ,
42414238 timeout : Io.Timeout ,
42424239) struct { ? net .Socket .ReceiveTimeoutError , usize } {
@@ -4246,10 +4243,6 @@ fn netReceivePosix(
42464243
42474244 // recvmmsg is useless, here's why:
42484245 // * [timeout bug](https://bugzilla.kernel.org/show_bug.cgi?id=75371)
4249- // * it wants iovecs for each message but we have a better API: one data
4250- // buffer to handle all the messages. The better API cannot be lowered to
4251- // the split vectors though because reducing the buffer size might make
4252- // some messages unreceivable.
42534246
42544247 // So the strategy instead is to use non-blocking recvmsg calls, calling
42554248 // poll() with timeout if the first one returns EAGAIN.
@@ -4267,7 +4260,6 @@ fn netReceivePosix(
42674260 },
42684261 };
42694262 var message_i : usize = 0 ;
4270- var data_i : usize = 0 ;
42714263
42724264 const deadline = timeout .toDeadline (t_io ) catch | err | return .{ err , message_i };
42734265
@@ -4276,14 +4268,15 @@ fn netReceivePosix(
42764268
42774269 if (message_buffer .len - message_i == 0 ) return .{ null , message_i };
42784270 const message = & message_buffer [message_i ];
4279- const remaining_data_buffer = data_buffer [data_i .. ];
42804271 var storage : PosixAddress = undefined ;
4281- var iov : posix.iovec = .{ .base = remaining_data_buffer .ptr , .len = remaining_data_buffer .len };
4272+
4273+ const iovecs : []posix.iovec = @ptrCast (message .data );
4274+
42824275 var msg : posix.msghdr = .{
42834276 .name = & storage .any ,
42844277 .namelen = @sizeOf (PosixAddress ),
4285- .iov = ( & iov )[0 .. 1] ,
4286- .iovlen = 1 ,
4278+ .iov = iovecs . ptr ,
4279+ .iovlen = @intCast ( iovecs . len ) ,
42874280 .control = message .control .ptr ,
42884281 .controllen = @intCast (message .control .len ),
42894282 .flags = undefined ,
@@ -4292,11 +4285,9 @@ fn netReceivePosix(
42924285 const recv_rc = posix .system .recvmsg (handle , & msg , posix_flags );
42934286 switch (posix .errno (recv_rc )) {
42944287 .SUCCESS = > {
4295- const data = remaining_data_buffer [0.. @intCast (recv_rc )];
4296- data_i += data .len ;
42974288 message .* = .{
42984289 .from = addressFromPosix (& storage ),
4299- .data = data ,
4290+ .data = message . data ,
43004291 .control = if (msg .control ) | ptr | @as ([* ]u8 , @ptrCast (ptr ))[0.. msg .controllen ] else message .control ,
43014292 .flags = .{
43024293 .eor = (msg .flags & posix .MSG .EOR ) != 0 ,
@@ -4305,6 +4296,7 @@ fn netReceivePosix(
43054296 .oob = (msg .flags & posix .MSG .OOB ) != 0 ,
43064297 .errqueue = if (@hasDecl (posix .MSG , "ERRQUEUE" )) (msg .flags & posix .MSG .ERRQUEUE ) != 0 else false ,
43074298 },
4299+ .bytes_received = @intCast (recv_rc ),
43084300 };
43094301 message_i += 1 ;
43104302 continue ;
@@ -4366,7 +4358,6 @@ fn netReceiveWindows(
43664358 userdata : ? * anyopaque ,
43674359 handle : net.Socket.Handle ,
43684360 message_buffer : []net.IncomingMessage ,
4369- data_buffer : []u8 ,
43704361 flags : net.ReceiveFlags ,
43714362 timeout : Io.Timeout ,
43724363) struct { ? net .Socket .ReceiveTimeoutError , usize } {
@@ -4375,7 +4366,6 @@ fn netReceiveWindows(
43754366 _ = t ;
43764367 _ = handle ;
43774368 _ = message_buffer ;
4378- _ = data_buffer ;
43794369 _ = flags ;
43804370 _ = timeout ;
43814371 @panic ("TODO implement netReceiveWindows" );
@@ -4385,14 +4375,12 @@ fn netReceiveUnavailable(
43854375 userdata : ? * anyopaque ,
43864376 handle : net.Socket.Handle ,
43874377 message_buffer : []net.IncomingMessage ,
4388- data_buffer : []u8 ,
43894378 flags : net.ReceiveFlags ,
43904379 timeout : Io.Timeout ,
43914380) struct { ? net .Socket .ReceiveTimeoutError , usize } {
43924381 _ = userdata ;
43934382 _ = handle ;
43944383 _ = message_buffer ;
4395- _ = data_buffer ;
43964384 _ = flags ;
43974385 _ = timeout ;
43984386 return .{ error .NetworkDown , 0 };
@@ -5387,8 +5375,7 @@ fn lookupDns(
53875375 for (mapped_nameservers ) | * ns | {
53885376 message_buffer [message_i ] = .{
53895377 .address = ns ,
5390- .data_ptr = query .ptr ,
5391- .data_len = query .len ,
5378+ .data = &[_ ][]const u8 {query },
53925379 };
53935380 message_i += 1 ;
53945381 }
@@ -5402,11 +5389,22 @@ fn lookupDns(
54025389 } };
54035390
54045391 while (true ) {
5405- var message_buffer : [max_messages ]Io.net.IncomingMessage = @splat ( .init ) ;
5392+ var message_buffer : [max_messages ]Io.net.IncomingMessage = undefined ;
54065393 const buf = answer_buffer [answer_buffer_i .. ];
5407- const recv_err , const recv_n = socket .receiveManyTimeout (t_io , & message_buffer , buf , .{}, timeout );
5394+
5395+ { // Partition buffer among messages - each gets equal share
5396+ const buf_per_message = @max (1 , buf .len / max_messages );
5397+ var data_buffers : [max_messages ][1 ][]u8 = undefined ;
5398+ var it = std .mem .window (u8 , buf , buf_per_message , buf_per_message );
5399+ for (& message_buffer , & data_buffers ) | * msg , * data_buf | {
5400+ data_buf [0 ] = @constCast (it .next () orelse &[_ ]u8 {});
5401+ msg .* = .init (data_buf );
5402+ }
5403+ }
5404+
5405+ const recv_err , const recv_n = socket .receiveManyTimeout (t_io , & message_buffer , .{}, timeout );
54085406 for (message_buffer [0.. recv_n ]) | * received_message | {
5409- const reply = received_message .data ;
5407+ const reply = received_message .data [ 0 ][0 .. received_message . bytes_received ] ;
54105408 // Ignore non-identifiable packets.
54115409 if (reply .len < 4 ) continue ;
54125410
@@ -5438,8 +5436,7 @@ fn lookupDns(
54385436 2 = > {
54395437 var retry_message : Io.net.OutgoingMessage = .{
54405438 .address = ns ,
5441- .data_ptr = query .ptr ,
5442- .data_len = query .len ,
5439+ .data = &.{query },
54435440 };
54445441 _ = netSendPosix (t , socket .handle , (& retry_message )[0.. 1], .{});
54455442 continue ;
0 commit comments