BOOL netconn_recv( netconn_t *conn, void *buf, size_t len, int flags, int *recvd ) { *recvd = 0; if (!netconn_connected( conn )) return FALSE; if (!len) return TRUE; if (conn->secure) { SIZE_T size, cread; BOOL res, eof; if (conn->peek_msg) { *recvd = min( len, conn->peek_len ); memcpy( buf, conn->peek_msg, *recvd ); conn->peek_len -= *recvd; conn->peek_msg += *recvd; if (conn->peek_len == 0) { heap_free( conn->peek_msg_mem ); conn->peek_msg_mem = NULL; conn->peek_msg = NULL; } /* check if we have enough data from the peek buffer */ if (!(flags & MSG_WAITALL) || *recvd == len) return TRUE; } size = *recvd; do { res = read_ssl_chunk(conn, (BYTE*)buf+size, len-size, &cread, &eof); if(!res) { WARN("read_ssl_chunk failed\n"); if(!size) return FALSE; break; } if(eof) { TRACE("EOF\n"); break; } size += cread; } while(!size || ((flags & MSG_WAITALL) && size < len)); TRACE("received %ld bytes\n", size); *recvd = size; return TRUE; } if ((*recvd = sock_recv( conn->socket, buf, len, flags )) == -1) { set_last_error( sock_get_error( errno ) ); return FALSE; } return TRUE; }
/****************************************************************************** * NETCON_recv * Basically calls 'recv()' unless we should use SSL * number of chars received is put in *recvd */ DWORD NETCON_recv(netconn_t *connection, void *buf, size_t len, BOOL blocking, int *recvd) { *recvd = 0; if (!len) return ERROR_SUCCESS; if (!connection->secure) { set_socket_blocking(connection, blocking); *recvd = sock_recv(connection->socket, buf, len, 0); return *recvd == -1 ? WSAGetLastError() : ERROR_SUCCESS; } else { SIZE_T size = 0; BOOL eof; DWORD res; if(connection->peek_msg) { size = min(len, connection->peek_len); memcpy(buf, connection->peek_msg, size); connection->peek_len -= size; connection->peek_msg += size; if(!connection->peek_len) { heap_free(connection->peek_msg_mem); connection->peek_msg_mem = connection->peek_msg = NULL; } *recvd = size; return ERROR_SUCCESS; } do { res = read_ssl_chunk(connection, (BYTE*)buf, len, blocking, &size, &eof); if(res != ERROR_SUCCESS) { if(res == WSAEWOULDBLOCK) { if(size) res = ERROR_SUCCESS; }else { WARN("read_ssl_chunk failed\n"); } break; } }while(!size && !eof); TRACE("received %ld bytes\n", size); *recvd = size; return res; } }
/****************************************************************************** * NETCON_recv * Basically calls 'recv()' unless we should use SSL * number of chars received is put in *recvd */ DWORD NETCON_recv(netconn_t *connection, void *buf, size_t len, blocking_mode_t mode, int *recvd) { *recvd = 0; if (!len) return ERROR_SUCCESS; if (!connection->secure) { int flags = 0; switch(mode) { case BLOCKING_ALLOW: break; case BLOCKING_DISALLOW: flags = WINE_MSG_DONTWAIT; break; case BLOCKING_WAITALL: flags = MSG_WAITALL; break; } set_socket_blocking(connection->socket, mode); *recvd = sock_recv(connection->socket, buf, len, flags); return *recvd == -1 ? sock_get_error(errno) : ERROR_SUCCESS; } else { SIZE_T size = 0, cread; BOOL eof; DWORD res; if(connection->peek_msg) { size = min(len, connection->peek_len); memcpy(buf, connection->peek_msg, size); connection->peek_len -= size; connection->peek_msg += size; if(!connection->peek_len) { heap_free(connection->peek_msg_mem); connection->peek_msg_mem = connection->peek_msg = NULL; } /* check if we have enough data from the peek buffer */ if(mode != BLOCKING_WAITALL || size == len) { *recvd = size; return ERROR_SUCCESS; } mode = BLOCKING_DISALLOW; } do { res = read_ssl_chunk(connection, (BYTE*)buf+size, len-size, mode, &cread, &eof); if(res != ERROR_SUCCESS) { if(res == WSAEWOULDBLOCK) { if(size) res = ERROR_SUCCESS; }else { WARN("read_ssl_chunk failed\n"); } break; } if(eof) { TRACE("EOF\n"); break; } size += cread; }while(!size || (mode == BLOCKING_WAITALL && size < len)); TRACE("received %zd bytes\n", size); *recvd = size; return res; } }
BOOL netconn_recv( netconn_t *conn, void *buf, size_t len, int flags, int *recvd ) { *recvd = 0; if (!netconn_connected( conn )) return FALSE; if (!len) return TRUE; if (conn->secure) { SIZE_T size, cread; BOOL res, eof; if (flags & ~(MSG_PEEK | MSG_WAITALL)) FIXME("SSL_read does not support the following flags: %08x\n", flags); if (flags & MSG_PEEK && conn->peek_msg) { if (len < conn->peek_len) FIXME("buffer isn't big enough, should we wrap?\n"); *recvd = min( len, conn->peek_len ); memcpy( buf, conn->peek_msg, *recvd ); return TRUE; } else if (conn->peek_msg) { *recvd = min( len, conn->peek_len ); memcpy( buf, conn->peek_msg, *recvd ); conn->peek_len -= *recvd; conn->peek_msg += *recvd; if (conn->peek_len == 0) { heap_free( conn->peek_msg_mem ); conn->peek_msg_mem = NULL; conn->peek_msg = NULL; } /* check if we have enough data from the peek buffer */ if (!(flags & MSG_WAITALL) || (*recvd == len)) return TRUE; } size = *recvd; do { res = read_ssl_chunk(conn, (BYTE*)buf+size, len-size, &cread, &eof); if(!res) { WARN("read_ssl_chunk failed\n"); if(!size) return FALSE; break; } if(eof) { TRACE("EOF\n"); break; } size += cread; }while(!size || ((flags & MSG_WAITALL) && size < len)); if(size && (flags & MSG_PEEK)) { conn->peek_msg_mem = conn->peek_msg = heap_alloc(size); if(!conn->peek_msg) return FALSE; memcpy(conn->peek_msg, buf, size); } TRACE("received %ld bytes\n", size); *recvd = size; return TRUE; } if ((*recvd = recv( conn->socket, buf, len, flags )) == -1) { set_last_error( sock_get_error( errno ) ); return FALSE; } return TRUE; }