Changes in uspace/srv/net/tcp/sock.c [7c912b6:0d520a2] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/net/tcp/sock.c
r7c912b6 r0d520a2 42 42 #include <ipc/services.h> 43 43 #include <ipc/socket.h> 44 #include <net/modules.h> 44 45 #include <net/socket.h> 45 46 #include <ns.h> … … 51 52 #include "ucall.h" 52 53 54 #define FRAGMENT_SIZE 1024 55 53 56 #define MAX_BACKLOG 128 54 57 … … 64 67 static void tcp_sock_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg); 65 68 static void tcp_sock_cstate_cb(tcp_conn_t *conn, void *arg); 66 static int tcp_sock_recv_fibril(void *arg);67 69 68 70 int tcp_sock_init(void) … … 96 98 async_exch_t *exch = async_exchange_begin(sock_core->sess); 97 99 async_msg_5(exch, NET_SOCKET_RECEIVED, (sysarg_t)sock_core->socket_id, 98 TCP_SOCK_FRAGMENT_SIZE, 0, 0, 1);100 FRAGMENT_SIZE, 0, 0, 1); 99 101 async_exchange_end(exch); 100 102 } … … 105 107 async_exch_t *exch = async_exchange_begin(lsock_core->sess); 106 108 async_msg_5(exch, NET_SOCKET_ACCEPTED, (sysarg_t)lsock_core->socket_id, 107 TCP_SOCK_FRAGMENT_SIZE, 0, 0, 0);109 FRAGMENT_SIZE, 0, 0, 0); 108 110 async_exchange_end(exch); 109 111 } 110 112 111 static int tcp_sock_create(tcp_client_t *client, tcp_sockdata_t **rsock)113 static void tcp_sock_socket(tcp_client_t *client, ipc_callid_t callid, ipc_call_t call) 112 114 { 113 115 tcp_sockdata_t *sock; 114 115 log_msg(LVL_DEBUG, "tcp_sock_create()");116 *rsock = NULL;117 118 sock = calloc(sizeof(tcp_sockdata_t), 1);119 if (sock == NULL)120 return ENOMEM;121 122 fibril_mutex_initialize(&sock->lock);123 sock->client = client;124 125 sock->recv_buffer_used = 0;126 sock->recv_error = TCP_EOK;127 fibril_mutex_initialize(&sock->recv_buffer_lock);128 fibril_condvar_initialize(&sock->recv_buffer_cv);129 list_initialize(&sock->ready);130 131 *rsock = sock;132 return EOK;133 }134 135 static void tcp_sock_uncreate(tcp_sockdata_t *sock)136 {137 log_msg(LVL_DEBUG, "tcp_sock_uncreate()");138 free(sock);139 }140 141 static int tcp_sock_finish_setup(tcp_sockdata_t *sock, int *sock_id)142 {143 116 socket_core_t *sock_core; 144 int rc;145 146 log_msg(LVL_DEBUG, "tcp_sock_finish_setup()");147 148 sock->recv_fibril = fibril_create(tcp_sock_recv_fibril, sock);149 if (sock->recv_fibril == 0)150 return ENOMEM;151 152 rc = socket_create(&sock->client->sockets, sock->client->sess,153 sock, sock_id);154 155 if (rc != EOK)156 return rc;157 158 sock_core = socket_cores_find(&sock->client->sockets, *sock_id);159 assert(sock_core != NULL);160 sock->sock_core = sock_core;161 162 return EOK;163 }164 165 static void tcp_sock_socket(tcp_client_t *client, ipc_callid_t callid, ipc_call_t call)166 {167 tcp_sockdata_t *sock;168 117 int sock_id; 169 118 int rc; … … 171 120 172 121 log_msg(LVL_DEBUG, "tcp_sock_socket()"); 173 174 rc = tcp_sock_create(client, &sock); 175 if (rc != EOK) { 176 async_answer_0(callid, rc); 177 return; 178 } 179 122 sock = calloc(sizeof(tcp_sockdata_t), 1); 123 if (sock == NULL) { 124 async_answer_0(callid, ENOMEM); 125 return; 126 } 127 128 fibril_mutex_initialize(&sock->lock); 129 sock->client = client; 180 130 sock->laddr.ipv4 = TCP_IPV4_ANY; 181 131 sock->lconn = NULL; 182 132 sock->backlog = 0; 133 list_initialize(&sock->ready); 183 134 184 135 sock_id = SOCKET_GET_SOCKET_ID(call); 185 rc = tcp_sock_finish_setup(sock, &sock_id);136 rc = socket_create(&client->sockets, client->sess, sock, &sock_id); 186 137 if (rc != EOK) { 187 tcp_sock_uncreate(sock);188 138 async_answer_0(callid, rc); 189 139 return; 190 140 } 191 141 142 sock_core = socket_cores_find(&client->sockets, sock_id); 143 assert(sock_core != NULL); 144 sock->sock_core = sock_core; 145 146 refresh_answer(&answer, NULL); 192 147 SOCKET_SET_SOCKET_ID(answer, sock_id); 193 148 194 SOCKET_SET_DATA_FRAGMENT_SIZE(answer, TCP_SOCK_FRAGMENT_SIZE);149 SOCKET_SET_DATA_FRAGMENT_SIZE(answer, FRAGMENT_SIZE); 195 150 SOCKET_SET_HEADER_SIZE(answer, sizeof(tcp_header_t)); 196 197 async_answer_3(callid, EOK, IPC_GET_ARG1(answer), 198 IPC_GET_ARG2(answer), IPC_GET_ARG3(answer)); 151 answer_call(callid, EOK, &answer, 3); 199 152 } 200 153 … … 408 361 } 409 362 410 if (rc == EOK)411 fibril_add_ready(socket->recv_fibril);412 413 363 async_answer_0(callid, rc); 364 365 /* Push one fragment notification to client's queue */ 366 tcp_sock_notify_data(sock_core); 367 log_msg(LVL_DEBUG, "tcp_sock_connect(): notify conn\n"); 414 368 } 415 369 … … 420 374 int asock_id; 421 375 socket_core_t *sock_core; 376 socket_core_t *asock_core; 422 377 tcp_sockdata_t *socket; 423 378 tcp_sockdata_t *asocket; … … 489 444 /* Allocate socket for accepted connection */ 490 445 491 rc = tcp_sock_create(client, &asocket); 492 if (rc != EOK) { 493 fibril_mutex_unlock(&socket->lock); 494 async_answer_0(callid, rc); 495 return; 496 } 497 446 log_msg(LVL_DEBUG, "tcp_sock_accept(): allocate asocket\n"); 447 asocket = calloc(sizeof(tcp_sockdata_t), 1); 448 if (asocket == NULL) { 449 fibril_mutex_unlock(&socket->lock); 450 async_answer_0(callid, ENOMEM); 451 return; 452 } 453 454 fibril_mutex_initialize(&asocket->lock); 455 asocket->client = client; 498 456 asocket->conn = conn; 499 457 log_msg(LVL_DEBUG, "tcp_sock_accept():create asocket\n"); 500 458 501 rc = tcp_sock_finish_setup(asocket, &asock_id);459 rc = socket_create(&client->sockets, client->sess, asocket, &asock_id); 502 460 if (rc != EOK) { 503 tcp_sock_uncreate(asocket);504 461 fibril_mutex_unlock(&socket->lock); 505 462 async_answer_0(callid, rc); 506 463 return; 507 464 } 508 509 fibril_add_ready(asocket->recv_fibril);510 511 465 log_msg(LVL_DEBUG, "tcp_sock_accept(): find acore\n"); 512 466 513 SOCKET_SET_DATA_FRAGMENT_SIZE(answer, TCP_SOCK_FRAGMENT_SIZE); 467 asock_core = socket_cores_find(&client->sockets, asock_id); 468 assert(asock_core != NULL); 469 470 refresh_answer(&answer, NULL); 471 472 SOCKET_SET_DATA_FRAGMENT_SIZE(answer, FRAGMENT_SIZE); 514 473 SOCKET_SET_SOCKET_ID(answer, asock_id); 515 474 SOCKET_SET_ADDRESS_LENGTH(answer, sizeof(struct sockaddr_in)); 516 517 async_answer_3(callid, asocket->sock_core->socket_id, 518 IPC_GET_ARG1(answer), IPC_GET_ARG2(answer), 519 IPC_GET_ARG3(answer)); 520 475 476 answer_call(callid, asock_core->socket_id, &answer, 3); 477 521 478 /* Push one fragment notification to client's queue */ 522 479 log_msg(LVL_DEBUG, "tcp_sock_accept(): notify data\n"); 480 tcp_sock_notify_data(asock_core); 523 481 fibril_mutex_unlock(&socket->lock); 524 482 } … … 534 492 ipc_callid_t wcallid; 535 493 size_t length; 536 uint8_t buffer[ TCP_SOCK_FRAGMENT_SIZE];494 uint8_t buffer[FRAGMENT_SIZE]; 537 495 tcp_error_t trc; 538 496 int rc; … … 565 523 } 566 524 567 if (length > TCP_SOCK_FRAGMENT_SIZE)568 length = TCP_SOCK_FRAGMENT_SIZE;525 if (length > FRAGMENT_SIZE) 526 length = FRAGMENT_SIZE; 569 527 570 528 rc = async_data_write_finalize(wcallid, buffer, length); … … 601 559 } 602 560 603 IPC_SET_ARG1(answer, 0); 604 SOCKET_SET_DATA_FRAGMENT_SIZE(answer, TCP_SOCK_FRAGMENT_SIZE); 605 async_answer_2(callid, EOK, IPC_GET_ARG1(answer), 606 IPC_GET_ARG2(answer)); 561 refresh_answer(&answer, NULL); 562 SOCKET_SET_DATA_FRAGMENT_SIZE(answer, FRAGMENT_SIZE); 563 answer_call(callid, EOK, &answer, 2); 607 564 fibril_mutex_unlock(&socket->lock); 608 565 } … … 623 580 ipc_call_t answer; 624 581 ipc_callid_t rcallid; 582 uint8_t buffer[FRAGMENT_SIZE]; 625 583 size_t data_len; 584 xflags_t xflags; 585 tcp_error_t trc; 626 586 struct sockaddr_in addr; 627 587 tcp_sock_t *rsock; … … 650 610 (void)flags; 651 611 652 log_msg(LVL_DEBUG, "tcp_sock_recvfrom(): lock recv_buffer_lock"); 653 fibril_mutex_lock(&socket->recv_buffer_lock); 654 while (socket->recv_buffer_used == 0 && socket->recv_error == TCP_EOK) { 655 log_msg(LVL_DEBUG, "wait for recv_buffer_cv + recv_buffer_used != 0"); 656 fibril_condvar_wait(&socket->recv_buffer_cv, 657 &socket->recv_buffer_lock); 658 } 659 660 log_msg(LVL_DEBUG, "Got data in sock recv_buffer"); 661 662 data_len = socket->recv_buffer_used; 663 rc = socket->recv_error; 664 665 switch (socket->recv_error) { 612 trc = tcp_uc_receive(socket->conn, buffer, FRAGMENT_SIZE, &data_len, 613 &xflags); 614 log_msg(LVL_DEBUG, "**** tcp_uc_receive done"); 615 616 switch (trc) { 666 617 case TCP_EOK: 667 618 rc = EOK; … … 678 629 } 679 630 680 log_msg(LVL_DEBUG, "**** recv result-> %d", rc);631 log_msg(LVL_DEBUG, "**** tcp_uc_receive -> %d", rc); 681 632 if (rc != EOK) { 682 fibril_mutex_unlock(&socket->recv_buffer_lock);683 633 fibril_mutex_unlock(&socket->lock); 684 634 async_answer_0(callid, rc); … … 695 645 log_msg(LVL_DEBUG, "addr read receive"); 696 646 if (!async_data_read_receive(&rcallid, &addr_length)) { 697 fibril_mutex_unlock(&socket->recv_buffer_lock);698 647 fibril_mutex_unlock(&socket->lock); 699 648 async_answer_0(callid, EINVAL); … … 707 656 rc = async_data_read_finalize(rcallid, &addr, addr_length); 708 657 if (rc != EOK) { 709 fibril_mutex_unlock(&socket->recv_buffer_lock);710 658 fibril_mutex_unlock(&socket->lock); 711 659 async_answer_0(callid, EINVAL); … … 716 664 log_msg(LVL_DEBUG, "data read receive"); 717 665 if (!async_data_read_receive(&rcallid, &length)) { 718 fibril_mutex_unlock(&socket->recv_buffer_lock);719 666 fibril_mutex_unlock(&socket->lock); 720 667 async_answer_0(callid, EINVAL); … … 726 673 727 674 log_msg(LVL_DEBUG, "data read finalize"); 728 rc = async_data_read_finalize(rcallid, socket->recv_buffer, length); 729 730 socket->recv_buffer_used -= length; 731 log_msg(LVL_DEBUG, "tcp_sock_recvfrom: %zu left in buffer", 732 socket->recv_buffer_used); 733 if (socket->recv_buffer_used > 0) { 734 memmove(socket->recv_buffer, socket->recv_buffer + length, 735 socket->recv_buffer_used); 736 tcp_sock_notify_data(socket->sock_core); 737 } 738 739 fibril_condvar_broadcast(&socket->recv_buffer_cv); 675 rc = async_data_read_finalize(rcallid, buffer, length); 740 676 741 677 if (length < data_len && rc == EOK) … … 743 679 744 680 SOCKET_SET_READ_DATA_LENGTH(answer, length); 745 async_answer_1(callid, EOK, IPC_GET_ARG1(answer)); 746 747 fibril_mutex_unlock(&socket->recv_buffer_lock); 681 answer_call(callid, EOK, &answer, 1); 682 683 /* Push one fragment notification to client's queue */ 684 tcp_sock_notify_data(sock_core); 748 685 fibril_mutex_unlock(&socket->lock); 749 686 } … … 756 693 tcp_error_t trc; 757 694 int rc; 695 uint8_t buffer[FRAGMENT_SIZE]; 696 size_t data_len; 697 xflags_t xflags; 758 698 759 699 log_msg(LVL_DEBUG, "tcp_sock_close()"); … … 776 716 return; 777 717 } 718 719 /* Drain incoming data. This should really be done in the background. */ 720 do { 721 trc = tcp_uc_receive(socket->conn, buffer, 722 FRAGMENT_SIZE, &data_len, &xflags); 723 } while (trc == TCP_EOK); 724 725 tcp_uc_delete(socket->conn); 778 726 } 779 727 … … 827 775 tcp_sock_notify_aconn(socket->sock_core); 828 776 fibril_mutex_unlock(&socket->lock); 829 }830 831 static int tcp_sock_recv_fibril(void *arg)832 {833 tcp_sockdata_t *sock = (tcp_sockdata_t *)arg;834 size_t data_len;835 xflags_t xflags;836 tcp_error_t trc;837 838 log_msg(LVL_DEBUG, "tcp_sock_recv_fibril()");839 840 while (true) {841 log_msg(LVL_DEBUG, "call tcp_uc_receive()");842 fibril_mutex_lock(&sock->recv_buffer_lock);843 while (sock->recv_buffer_used != 0)844 fibril_condvar_wait(&sock->recv_buffer_cv,845 &sock->recv_buffer_lock);846 847 trc = tcp_uc_receive(sock->conn, sock->recv_buffer,848 TCP_SOCK_FRAGMENT_SIZE, &data_len, &xflags);849 850 if (trc != TCP_EOK) {851 sock->recv_error = trc;852 fibril_condvar_broadcast(&sock->recv_buffer_cv);853 fibril_mutex_unlock(&sock->recv_buffer_lock);854 tcp_sock_notify_data(sock->sock_core);855 break;856 }857 858 log_msg(LVL_DEBUG, "got data - broadcast recv_buffer_cv");859 860 sock->recv_buffer_used = data_len;861 fibril_condvar_broadcast(&sock->recv_buffer_cv);862 fibril_mutex_unlock(&sock->recv_buffer_lock);863 tcp_sock_notify_data(sock->sock_core);864 }865 866 tcp_uc_delete(sock->conn);867 868 return 0;869 777 } 870 778
Note:
See TracChangeset
for help on using the changeset viewer.