diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index e22d328a34..ee45c7b375 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -751,13 +751,6 @@ static int pdp_recv_postoffice(int idx, SceNetEtherAddr *saddr, uint16_t *sport, SceNetEtherAddr saddr_copy = {0}; int len_copy = *len; - if (len_copy > AEMU_POSTOFFICE_PDP_BLOCK_MAX) { - // trim, library limites pdp packets - // some games just provide amazingly huge buffer sizes during recv - // if a huge packet cannot be sent, it is logged on the sender side - len_copy = AEMU_POSTOFFICE_PDP_BLOCK_MAX; - } - int pdp_recv_status = pdp_recv(pdp_sock, (char *)&saddr_copy, &sport_copy, (char *)data, &len_copy, true); if (pdp_recv_status == AEMU_POSTOFFICE_CLIENT_SESSION_DEAD) { handle_relay_connect_failure(); @@ -768,10 +761,6 @@ static int pdp_recv_postoffice(int idx, SceNetEtherAddr *saddr, uint16_t *sport, if (pdp_recv_status == AEMU_POSTOFFICE_CLIENT_SESSION_WOULD_BLOCK) { return SOCKET_ERROR; } - if (pdp_recv_status == AEMU_POSTOFFICE_CLIENT_OUT_OF_MEMORY) { - // this is pretty critical - ERROR_LOG(Log::sceNet, "%s: critical: huge client buf %d what is going on please fix", __func__, *len); - } *len = len_copy; if (saddr != NULL) { @@ -1155,12 +1144,6 @@ static int ptp_recv_postoffice(int idx, void *data, int *len) { } int len_copy = *len; - if (len_copy > AEMU_POSTOFFICE_PTP_BLOCK_MAX) { - // trim, library limit - // some games just provide amazingly huge buffer sizes during recv - // if a huge burst cannot be sent, it is logged on the sender side - len_copy = AEMU_POSTOFFICE_PTP_BLOCK_MAX; - } int ptp_recv_status = ptp_recv(internal->postofficeHandle, (char *)data, &len_copy, true); if (ptp_recv_status == AEMU_POSTOFFICE_CLIENT_SESSION_DEAD) { @@ -1172,10 +1155,6 @@ static int ptp_recv_postoffice(int idx, void *data, int *len) { if (ptp_recv_status == AEMU_POSTOFFICE_CLIENT_SESSION_WOULD_BLOCK) { return SCE_NET_ADHOC_ERROR_WOULD_BLOCK; } - if (ptp_recv_status == AEMU_POSTOFFICE_CLIENT_OUT_OF_MEMORY) { - // this is pretty critical - ERROR_LOG(Log::sceNet, "%s: critical: huge client buf %d what is going on please fix", __func__, *len); - } // AEMU_POSTOFFICE_CLIENT_SESSION_DATA_TRUNC is okay, it just means it has data in it's user space buffer @@ -2808,27 +2787,78 @@ int sceNetAdhocSetSocketAlert(int id, int flag) { return hleDelayResult(hleLogDebug(Log::sceNet, retval), "set socket alert delay", 1000); } -static int get_postoffice_fd(int idx) { +static bool postoffice_can_recv_or_listen_has_request(int idx) { AdhocSocket *internal = adhocSockets[idx]; if (internal->type == SOCK_PTP) { if (internal->data.ptp.state == ADHOC_PTP_STATE_LISTEN) { - void *socket = ptp_listen_postoffice_recover(idx); - if (socket != NULL) { - return ptp_listen_get_native_sock(socket); + void *ptp_listen_handle = ptp_listen_postoffice_recover(idx); + if (ptp_listen_handle == NULL) { + return false; } - } else { - void *socket = internal->postofficeHandle; - if (socket != NULL) { - return ptp_get_native_sock(socket); + int has_request = ptp_listen_has_request(ptp_listen_handle); + if (has_request == AEMU_POSTOFFICE_CLIENT_SESSION_DEAD) { + internal->postofficeHandle = NULL; + ptp_listen_close(ptp_listen_handle); + return false; + } + if (has_request) { + return true; + } + } else if (internal->data.ptp.state == ADHOC_PTP_STATE_ESTABLISHED) { + void *ptp_handle = internal->postofficeHandle; + if (ptp_handle == NULL) { + return false; + } + int peek_len = ptp_peek_next_size(ptp_handle); + if (peek_len == AEMU_POSTOFFICE_CLIENT_SESSION_DEAD) { + return false; + } + if (peek_len > 0) { + return true; } } } else { - void *socket = pdp_postoffice_recover(idx); - if (socket != NULL){ - return pdp_get_native_sock(socket); + void *pdp_handle = pdp_postoffice_recover(idx); + if (pdp_handle == NULL){ + return false; + } + int peek_len = pdp_buffered_data_size(pdp_handle); + if (peek_len == AEMU_POSTOFFICE_CLIENT_SESSION_DEAD) { + internal->postofficeHandle = NULL; + pdp_delete(pdp_handle); + return false; + } + if (peek_len > 0) { + return true; } } - return -1; + return false; +} + +static bool postoffice_can_send(int idx) { + AdhocSocket *internal = adhocSockets[idx]; + if (internal->type == SOCK_PTP && internal->data.ptp.state == ADHOC_PTP_STATE_ESTABLISHED) { + void *ptp_handle = internal->postofficeHandle; + if (ptp_handle == NULL) { + return false; + } + if (ptp_is_dead(ptp_handle)) { + return false; + } + return ptp_send_buf_not_full(ptp_handle); + } else { + void *pdp_handle = pdp_postoffice_recover(idx); + if (pdp_handle == NULL){ + return false; + } + if (pdp_is_dead(pdp_handle)) { + internal->postofficeHandle = NULL; + pdp_delete(pdp_handle); + return false; + } + return pdp_send_buf_not_full(pdp_handle); + } + return false; } int PollAdhocSocket(SceNetAdhocPollSd* sds, int count, int timeout, int nonblock) { @@ -2848,11 +2878,7 @@ int PollAdhocSocket(SceNetAdhocPollSd* sds, int count, int timeout, int nonblock } if (serverHasRelay) { - int postoffice_fd = get_postoffice_fd(sds[i].id - 1); - if (postoffice_fd == -1) { - continue; - } - fd = postoffice_fd; + continue; } else { if (sock->type == SOCK_PTP) { fd = sock->data.ptp.id; @@ -2871,20 +2897,16 @@ int PollAdhocSocket(SceNetAdhocPollSd* sds, int count, int timeout, int nonblock timeval tmout; tmout.tv_sec = timeout / 1000000; // seconds tmout.tv_usec = (timeout % 1000000); // microseconds - int affectedsockets = select(maxfd + 1, &readfds, &writefds, &exceptfds, &tmout); + int affectedsockets = 0; + if (!serverHasRelay) + affectedsockets = select(maxfd + 1, &readfds, &writefds, &exceptfds, &tmout); if (affectedsockets >= 0) { affectedsockets = 0; for (int i = 0; i < count; i++) { if (sds[i].id > 0 && sds[i].id <= MAX_SOCKET && adhocSockets[sds[i].id - 1] != NULL) { auto sock = adhocSockets[sds[i].id - 1]; - if (serverHasRelay) { - int postoffice_fd = get_postoffice_fd(sds[i].id - 1); - if (postoffice_fd == -1) { - continue; - } - fd = postoffice_fd; - } else { + if (!serverHasRelay) { if (sock->type == SOCK_PTP) { fd = sock->data.ptp.id; } @@ -2892,19 +2914,32 @@ int PollAdhocSocket(SceNetAdhocPollSd* sds, int count, int timeout, int nonblock fd = sock->data.pdp.id; } } - if ((sds[i].events & ADHOC_EV_RECV) && FD_ISSET(fd, &readfds)) - sds[i].revents |= ADHOC_EV_RECV; - if ((sds[i].events & ADHOC_EV_SEND) && FD_ISSET(fd, &writefds)) - sds[i].revents |= ADHOC_EV_SEND; - if (sock->alerted_flags) - sds[i].revents |= ADHOC_EV_ALERT; + if (serverHasRelay) { + if ((sds[i].events & ADHOC_EV_RECV) && postoffice_can_recv_or_listen_has_request(sds[i].id - 1)) + sds[i].revents |= ADHOC_EV_RECV; + if ((sds[i].events & ADHOC_EV_SEND) && postoffice_can_send(sds[i].id - 1)) + sds[i].revents |= ADHOC_EV_SEND; + } else { + if ((sds[i].events & ADHOC_EV_RECV) && FD_ISSET(fd, &readfds)) + sds[i].revents |= ADHOC_EV_RECV; + if ((sds[i].events & ADHOC_EV_SEND) && FD_ISSET(fd, &writefds)) + sds[i].revents |= ADHOC_EV_SEND; + if (sock->alerted_flags) + sds[i].revents |= ADHOC_EV_ALERT; + } // Mask certain revents bits with events bits sds[i].revents &= sds[i].events; if (sock->type == SOCK_PTP) { // FIXME: Should we also make use "retry_interval" for ADHOC_EV_ACCEPT, similar to ADHOC_EV_CONNECT ? - if (sock->data.ptp.state == ADHOC_PTP_STATE_LISTEN && (sds[i].events & ADHOC_EV_ACCEPT) && FD_ISSET(fd, &readfds)) { - sds[i].revents |= ADHOC_EV_ACCEPT; + if ((sds[i].events & ADHOC_EV_ACCEPT) && sock->data.ptp.state == ADHOC_PTP_STATE_LISTEN) { + if (serverHasRelay) { + if (postoffice_can_recv_or_listen_has_request(sds[i].id - 1)) + sds[i].revents |= ADHOC_EV_ACCEPT; + } else { + if (FD_ISSET(fd, &readfds)) + sds[i].revents |= ADHOC_EV_ACCEPT; + } } // Fate Unlimited Codes and Carnage Heart EXA relies on AdhocPollSocket in order to retry a failed PtpConnect, but the interval must not be too long (about 1 frame before state became Established by GetPtpStat) for Bleach Heat the Soul 7 to work properly. else if ((sds[i].events & ADHOC_EV_CONNECT) && ((sock->data.ptp.state == ADHOC_PTP_STATE_CLOSED && sock->attemptCount == 0) || @@ -3944,7 +3979,7 @@ static int sceNetAdhocGetPdpStat(u32 structSize, u32 structAddr) { if (serverHasRelay) { void *postofficeHandle = pdp_postoffice_recover(j); if (postofficeHandle != NULL) { - sock->data.pdp.rcv_sb_cc = pdp_peek_next_size(postofficeHandle); + sock->data.pdp.rcv_sb_cc = pdp_buffered_data_size(postofficeHandle); } } else { sock->data.pdp.rcv_sb_cc = getAvailToRecv(sock->data.pdp.id, sock->buffer_size); diff --git a/ext/aemu_postoffice b/ext/aemu_postoffice index 530fee545c..d4dd0e90f4 160000 --- a/ext/aemu_postoffice +++ b/ext/aemu_postoffice @@ -1 +1 @@ -Subproject commit 530fee545c27ffb8524a8f496cbbcfdb687fe8c5 +Subproject commit d4dd0e90f411b7cd1a1a38610a3712f2b46a6bc7