@@ -234,6 +234,7 @@ static u8 _net_error_code_map[] = {
234234 ETIMEDOUT ,
235235};
236236
237+ static const s32 maxblocksize = (NET_HEAP_SIZE /2 );
237238static volatile bool _init_busy = false;
238239static volatile bool _init_abort = false;
239240static vs32 _last_init_result = - ENETDOWN ;
@@ -890,35 +891,50 @@ s32 net_sendto(s32 s, const void *data, s32 len, u32 flags, struct sockaddr *to,
890891
891892 if (net_ip_top_fd < 0 ) return - ENXIO ;
892893 if (tolen > 28 ) return - EOVERFLOW ;
893-
894- message_buf = net_malloc (len );
894+
895+ s32 blockSize = len > maxblocksize ? maxblocksize : len ;
896+ message_buf = net_malloc (blockSize );
895897 if (message_buf == NULL ) {
896- debug_printf ("net_send: failed to alloc %d bytes\n" , len );
898+ debug_printf ("net_send: failed to alloc %d bytes\n" , blockSize );
897899 return IPC_ENOMEM ;
898900 }
901+
902+ for (ret = 0 ; ret < len ;)
903+ {
904+ blockSize = len - ret ;
905+ if (blockSize > maxblocksize )
906+ blockSize = maxblocksize ;
907+
908+ debug_printf ("net_sendto(%d, %p, %d, %d, %p, %d)\n" , s , data + ret , blockSize , flags , to , tolen );
909+ if (to && to -> sa_len != tolen ) {
910+ debug_printf ("warning: to->sa_len was %d, setting to %d\n" , to -> sa_len , tolen );
911+ to -> sa_len = tolen ;
912+ }
913+
914+ memset (params , 0 , sizeof (struct sendto_params ));
915+ memcpy (message_buf , data + ret , blockSize ); // ensure message buf is aligned
916+
917+ params -> socket = s ;
918+ params -> flags = flags ;
919+ if (to ) {
920+ params -> has_destaddr = 1 ;
921+ memcpy (params -> destaddr , to , to -> sa_len );
922+ } else {
923+ params -> has_destaddr = 0 ;
924+ }
899925
900- debug_printf ("net_sendto(%d, %p, %d, %d, %p, %d)\n" , s , data , len , flags , to , tolen );
901-
902- if (to && to -> sa_len != tolen ) {
903- debug_printf ("warning: to->sa_len was %d, setting to %d\n" , to -> sa_len , tolen );
904- to -> sa_len = tolen ;
905- }
906-
907- memset (params , 0 , sizeof (struct sendto_params ));
908- memcpy (message_buf , data , len ); // ensure message buf is aligned
909-
910- params -> socket = s ;
911- params -> flags = flags ;
912- if (to ) {
913- params -> has_destaddr = 1 ;
914- memcpy (params -> destaddr , to , to -> sa_len );
915- } else {
916- params -> has_destaddr = 0 ;
926+ s32 sent = _net_convert_error (IOS_IoctlvFormat (__net_hid , net_ip_top_fd , IOCTLV_SO_SENDTO , "dd:" , message_buf , blockSize , params , sizeof (struct sendto_params )));
927+ debug_printf ("net_send retuned %d\n" , sent );
928+
929+ if (sent <= 0 )
930+ {
931+ ret = sent ;
932+ break ;
933+ }
934+
935+ ret += sent ;
917936 }
918937
919- ret = _net_convert_error (IOS_IoctlvFormat (__net_hid , net_ip_top_fd , IOCTLV_SO_SENDTO , "dd:" , message_buf , len , params , sizeof (struct sendto_params )));
920- debug_printf ("net_send retuned %d\n" , ret );
921-
922938 if (message_buf != NULL ) net_free (message_buf );
923939 return ret ;
924940}
@@ -941,35 +957,56 @@ s32 net_recvfrom(s32 s, void *mem, s32 len, u32 flags, struct sockaddr *from, so
941957 debug_printf ("warning: from->sa_len was %d, setting to %d\n" ,from -> sa_len , * fromlen );
942958 from -> sa_len = * fromlen ;
943959 }
944-
945- message_buf = net_malloc (len );
960+
961+ s32 blockSize = len > maxblocksize ? maxblocksize : len ;
962+ message_buf = net_malloc (blockSize );
946963 if (message_buf == NULL ) {
947- debug_printf ("SORecv: failed to alloc %d bytes\n" , len );
964+ debug_printf ("SORecv: failed to alloc %d bytes\n" , blockSize );
948965 return IPC_ENOMEM ;
949966 }
950-
951- debug_printf ("net_recvfrom(%d, '%s', %d, %d, %p, %d)\n" , s , (char * )mem , len , flags , from , fromlen ?* fromlen :0 );
952-
953- memset (message_buf , 0 , len );
954- params [0 ] = s ;
955- params [1 ] = flags ;
956-
957- ret = _net_convert_error (IOS_IoctlvFormat (__net_hid , net_ip_top_fd , IOCTLV_SO_RECVFROM , "d:dd" , params , 8 , message_buf , len , from , (fromlen ?* fromlen :0 )));
958- debug_printf ("net_recvfrom returned %d\n" , ret );
959-
960- if (ret > 0 ) {
961- if (ret > len ) {
967+
968+ for (ret = 0 ; ret < len ;)
969+ {
970+ blockSize = len - ret ;
971+ if (blockSize > maxblocksize )
972+ blockSize = maxblocksize ;
973+
974+ debug_printf ("net_recvfrom(%d, '%s', %d, %d, %p, %d)\n" , s , (char * )mem , blockSize , flags , from , fromlen ?* fromlen :0 );
975+
976+ memset (message_buf , 0 , blockSize );
977+ params [0 ] = s ;
978+ params [1 ] = flags ;
979+
980+ s32 received = _net_convert_error (IOS_IoctlvFormat (__net_hid , net_ip_top_fd , IOCTLV_SO_RECVFROM , "d:dd" , params , 8 , message_buf , blockSize , from , (fromlen ?* fromlen :0 )));
981+ debug_printf ("net_recvfrom returned %d\n" , received );
982+
983+ //connection closed(0) or error(<0)
984+ if (received <= 0 )
985+ {
986+ if (fromlen && from ) * fromlen = from -> sa_len ;
987+ ret = received ;
988+ break ;
989+ }
990+
991+ //well something went wrong lol
992+ if (received > blockSize )
993+ {
962994 ret = - EOVERFLOW ;
963- goto done ;
995+ break ;
964996 }
965-
966- memcpy (mem , message_buf , ret );
997+
998+ if (fromlen && from ) * fromlen = from -> sa_len ;
999+ memcpy (mem + ret , message_buf , received );
1000+ ret += received ;
1001+
1002+ //we got a partial read, so we break and report the partial read
1003+ if (received != blockSize )
1004+ break ;
9671005 }
968-
969- if (fromlen && from ) * fromlen = from -> sa_len ;
970-
971- done :
972- if (message_buf != NULL ) net_free (message_buf );
1006+
1007+ if (message_buf != NULL )
1008+ net_free (message_buf );
1009+
9731010 return ret ;
9741011}
9751012
0 commit comments