Changes in uspace/srv/net/tl/tcp/sock.c [ae481e0:d9e14fa4] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/net/tl/tcp/sock.c
rae481e0 rd9e14fa4 52 52 #define FRAGMENT_SIZE 1024 53 53 54 #define MAX_BACKLOG 12855 56 54 /** Free ports pool start. */ 57 55 #define TCP_FREE_PORTS_START 1025 … … 62 60 static int last_used_port = TCP_FREE_PORTS_START - 1; 63 61 static socket_ports_t gsock; 64 65 static void tcp_sock_cstate_cb(tcp_conn_t *conn, void *arg);66 62 67 63 void tcp_sock_init(void) … … 99 95 { 100 96 tcp_sockdata_t *sock; 101 socket_core_t *sock_core;102 97 int sock_id; 103 98 int rc; … … 111 106 } 112 107 113 fibril_mutex_initialize(&sock->lock);114 108 sock->client = client; 115 109 sock->laddr.ipv4 = TCP_IPV4_ANY; 116 sock->lconn = NULL;117 sock->backlog = 0;118 list_initialize(&sock->ready);119 110 120 111 sock_id = SOCKET_GET_SOCKET_ID(call); … … 124 115 return; 125 116 } 126 127 sock_core = socket_cores_find(&client->sockets, sock_id);128 assert(sock_core != NULL);129 sock->sock_core = sock_core;130 117 131 118 refresh_answer(&answer, NULL); … … 180 167 socket_core_t *sock_core; 181 168 tcp_sockdata_t *socket; 182 tcp_error_t trc;183 tcp_sock_t lsocket;184 tcp_sock_t fsocket;185 tcp_conn_t *conn;186 tcp_sock_lconn_t *lconn;187 int i;188 169 189 170 log_msg(LVL_DEBUG, "tcp_sock_listen()"); … … 196 177 return; 197 178 } 198 199 if (backlog > MAX_BACKLOG)200 backlog = MAX_BACKLOG;201 179 202 180 sock_core = socket_cores_find(&client->sockets, socket_id); … … 209 187 210 188 /* 211 * Prepare @c backlog listening connections. 189 * XXX We do not do anything and defer action to accept(). 190 * This is a slight difference in semantics, but most servers 191 * would just listen() and immediately accept() in a loop. 192 * 193 * The only difference is that there is a window between 194 * listen() and accept() or two accept()s where we refuse 195 * connections. 212 196 */ 213 fibril_mutex_lock(&socket->lock); 214 215 socket->backlog = backlog; 216 socket->lconn = calloc(sizeof(tcp_conn_t *), backlog); 217 if (socket->lconn == NULL) { 218 fibril_mutex_unlock(&socket->lock); 219 async_answer_0(callid, ENOMEM); 220 return; 221 } 222 223 log_msg(LVL_DEBUG, " - open connections"); 224 225 lsocket.addr.ipv4 = TCP_IPV4_ANY; 226 lsocket.port = sock_core->port; 227 fsocket.addr.ipv4 = TCP_IPV4_ANY; 228 fsocket.port = TCP_PORT_ANY; 229 230 for (i = 0; i < backlog; i++) { 231 232 lconn = calloc(sizeof(tcp_sock_lconn_t), 1); 233 if (lconn == NULL) { 234 /* XXX Clean up */ 235 fibril_mutex_unlock(&socket->lock); 236 async_answer_0(callid, ENOMEM); 237 return; 238 } 239 240 trc = tcp_uc_open(&lsocket, &fsocket, ap_passive, 241 tcp_open_nonblock, &conn); 242 if (conn == NULL) { 243 /* XXX Clean up */ 244 fibril_mutex_unlock(&socket->lock); 245 async_answer_0(callid, ENOMEM); 246 return; 247 } 248 249 tcp_uc_set_cstate_cb(conn, tcp_sock_cstate_cb, lconn); 250 251 assert(trc == TCP_EOK); 252 conn->name = (char *)"S"; 253 254 lconn->conn = conn; 255 lconn->socket = socket; 256 link_initialize(&lconn->ready_list); 257 socket->lconn[i] = lconn; 258 } 259 260 fibril_mutex_unlock(&socket->lock); 197 (void)backlog; 198 (void)socket; 199 261 200 async_answer_0(callid, EOK); 201 log_msg(LVL_DEBUG, "tcp_sock_listen(): notify data\n"); 202 /* Push one accept notification to client's queue */ 203 tcp_sock_notify_aconn(sock_core); 262 204 } 263 205 … … 273 215 tcp_sock_t lsocket; 274 216 tcp_sock_t fsocket; 275 nic_device_id_t dev_id;217 device_id_t dev_id; 276 218 tcp_phdr_t *phdr; 277 219 size_t phdr_len; … … 306 248 } 307 249 308 fibril_mutex_lock(&socket->lock);309 310 250 if (socket->laddr.ipv4 == TCP_IPV4_ANY) { 311 251 /* Find route to determine local IP address. */ … … 314 254 (void **)&phdr, &phdr_len); 315 255 if (rc != EOK) { 316 fibril_mutex_unlock(&socket->lock);317 256 async_answer_0(callid, rc); 318 257 log_msg(LVL_DEBUG, "tcp_transmit_connect: Failed to find route."); … … 330 269 fsocket.port = uint16_t_be2host(addr->sin_port); 331 270 332 trc = tcp_uc_open(&lsocket, &fsocket, ap_active, 0,&socket->conn);271 trc = tcp_uc_open(&lsocket, &fsocket, ap_active, &socket->conn); 333 272 334 273 if (socket->conn != NULL) 335 274 socket->conn->name = (char *)"C"; 336 337 fibril_mutex_unlock(&socket->lock);338 275 339 276 switch (trc) { … … 368 305 tcp_sock_t fsocket; 369 306 tcp_conn_t *conn; 370 tcp_conn_t *rconn;371 tcp_sock_lconn_t *lconn;372 307 int rc; 373 308 … … 384 319 385 320 socket = (tcp_sockdata_t *)sock_core->specific_data; 386 fibril_mutex_lock(&socket->lock);387 321 388 322 log_msg(LVL_DEBUG, " - verify socket->conn"); 389 323 if (socket->conn != NULL) { 390 fibril_mutex_unlock(&socket->lock);391 324 async_answer_0(callid, EINVAL); 392 325 return; 393 326 } 394 327 395 if (list_empty(&socket->ready)) { 396 fibril_mutex_unlock(&socket->lock); 397 async_answer_0(callid, ENOENT); 398 return; 399 } 400 401 lconn = list_get_instance(list_first(&socket->ready), 402 tcp_sock_lconn_t, ready_list); 403 list_remove(&lconn->ready_list); 404 405 conn = lconn->conn; 406 tcp_uc_set_cstate_cb(conn, NULL, NULL); 407 408 /* Replenish listening connection */ 328 log_msg(LVL_DEBUG, " - open connection"); 409 329 410 330 lsocket.addr.ipv4 = TCP_IPV4_ANY; … … 413 333 fsocket.port = TCP_PORT_ANY; 414 334 415 trc = tcp_uc_open(&lsocket, &fsocket, ap_passive, tcp_open_nonblock, 416 &rconn); 417 if (rconn == NULL) { 418 /* XXX Clean up */ 419 fibril_mutex_unlock(&socket->lock); 420 async_answer_0(callid, ENOMEM); 421 return; 422 } 423 424 tcp_uc_set_cstate_cb(rconn, tcp_sock_cstate_cb, lconn); 425 426 assert(trc == TCP_EOK); 427 rconn->name = (char *)"S"; 428 429 lconn->conn = rconn; 430 431 /* Allocate socket for accepted connection */ 335 trc = tcp_uc_open(&lsocket, &fsocket, ap_passive, &conn); 336 if (conn != NULL) 337 conn->name = (char *)"S"; 338 339 log_msg(LVL_DEBUG, " - decode TCP return code"); 340 341 switch (trc) { 342 case TCP_EOK: 343 rc = EOK; 344 break; 345 case TCP_ERESET: 346 rc = ECONNABORTED; 347 break; 348 default: 349 assert(false); 350 } 351 352 log_msg(LVL_DEBUG, " - check TCP return code"); 353 if (rc != EOK) { 354 async_answer_0(callid, rc); 355 return; 356 } 432 357 433 358 log_msg(LVL_DEBUG, "tcp_sock_accept(): allocate asocket\n"); 434 359 asocket = calloc(sizeof(tcp_sockdata_t), 1); 435 360 if (asocket == NULL) { 436 fibril_mutex_unlock(&socket->lock);437 361 async_answer_0(callid, ENOMEM); 438 362 return; 439 363 } 440 364 441 fibril_mutex_initialize(&asocket->lock);442 365 asocket->client = client; 443 366 asocket->conn = conn; … … 446 369 rc = socket_create(&client->sockets, client->sess, asocket, &asock_id); 447 370 if (rc != EOK) { 448 fibril_mutex_unlock(&socket->lock);449 371 async_answer_0(callid, rc); 450 372 return; … … 463 385 answer_call(callid, asock_core->socket_id, &answer, 3); 464 386 387 /* Push one accept notification to client's queue */ 388 tcp_sock_notify_aconn(sock_core); 389 465 390 /* Push one fragment notification to client's queue */ 466 log_msg(LVL_DEBUG, "tcp_sock_accept(): notify data\n");467 391 tcp_sock_notify_data(asock_core); 468 fibril_mutex_unlock(&socket->lock);392 log_msg(LVL_DEBUG, "tcp_sock_accept(): notify aconn\n"); 469 393 } 470 394 … … 495 419 496 420 socket = (tcp_sockdata_t *)sock_core->specific_data; 497 fibril_mutex_lock(&socket->lock);498 499 421 if (socket->conn == NULL) { 500 fibril_mutex_unlock(&socket->lock);501 422 async_answer_0(callid, ENOTCONN); 502 423 return; … … 505 426 for (index = 0; index < fragments; index++) { 506 427 if (!async_data_write_receive(&wcallid, &length)) { 507 fibril_mutex_unlock(&socket->lock);508 428 async_answer_0(callid, EINVAL); 509 429 return; … … 515 435 rc = async_data_write_finalize(wcallid, buffer, length); 516 436 if (rc != EOK) { 517 fibril_mutex_unlock(&socket->lock);518 437 async_answer_0(callid, rc); 519 438 return; … … 540 459 541 460 if (rc != EOK) { 542 fibril_mutex_unlock(&socket->lock);543 461 async_answer_0(callid, rc); 544 462 return; … … 549 467 SOCKET_SET_DATA_FRAGMENT_SIZE(answer, FRAGMENT_SIZE); 550 468 answer_call(callid, EOK, &answer, 2); 551 fibril_mutex_unlock(&socket->lock);552 469 } 553 470 … … 587 504 588 505 socket = (tcp_sockdata_t *)sock_core->specific_data; 589 fibril_mutex_lock(&socket->lock);590 591 506 if (socket->conn == NULL) { 592 fibril_mutex_unlock(&socket->lock);593 507 async_answer_0(callid, ENOTCONN); 594 508 return; … … 618 532 log_msg(LVL_DEBUG, "**** tcp_uc_receive -> %d", rc); 619 533 if (rc != EOK) { 620 fibril_mutex_unlock(&socket->lock);621 534 async_answer_0(callid, rc); 622 535 return; … … 632 545 log_msg(LVL_DEBUG, "addr read receive"); 633 546 if (!async_data_read_receive(&rcallid, &addr_length)) { 634 fibril_mutex_unlock(&socket->lock);635 547 async_answer_0(callid, EINVAL); 636 548 return; … … 643 555 rc = async_data_read_finalize(rcallid, &addr, addr_length); 644 556 if (rc != EOK) { 645 fibril_mutex_unlock(&socket->lock);646 557 async_answer_0(callid, EINVAL); 647 558 return; … … 651 562 log_msg(LVL_DEBUG, "data read receive"); 652 563 if (!async_data_read_receive(&rcallid, &length)) { 653 fibril_mutex_unlock(&socket->lock);654 564 async_answer_0(callid, EINVAL); 655 565 return; … … 670 580 /* Push one fragment notification to client's queue */ 671 581 tcp_sock_notify_data(sock_core); 672 fibril_mutex_unlock(&socket->lock);673 582 } 674 583 … … 694 603 695 604 socket = (tcp_sockdata_t *)sock_core->specific_data; 696 fibril_mutex_lock(&socket->lock); 697 698 if (socket->conn != NULL) { 699 trc = tcp_uc_close(socket->conn); 700 if (trc != TCP_EOK && trc != TCP_ENOTEXIST) { 701 fibril_mutex_unlock(&socket->lock); 702 async_answer_0(callid, EBADF); 703 return; 704 } 705 706 /* Drain incoming data. This should really be done in the background. */ 707 do { 708 trc = tcp_uc_receive(socket->conn, buffer, 709 FRAGMENT_SIZE, &data_len, &xflags); 710 } while (trc == TCP_EOK); 711 712 tcp_uc_delete(socket->conn); 713 } 605 rc = tcp_uc_close(socket->conn); 606 if (rc != EOK) { 607 async_answer_0(callid, rc); 608 return; 609 } 610 611 /* Drain incoming data. This should really be done in the background. */ 612 do { 613 trc = tcp_uc_receive(socket->conn, buffer, FRAGMENT_SIZE, 614 &data_len, &xflags); 615 } while (trc == TCP_EOK); 714 616 715 617 rc = socket_destroy(net_sess, socket_id, &client->sockets, &gsock, 716 618 tcp_free_sock_data); 717 619 if (rc != EOK) { 718 fibril_mutex_unlock(&socket->lock); 719 async_answer_0(callid, rc); 720 return; 721 } 722 723 fibril_mutex_unlock(&socket->lock); 620 async_answer_0(callid, rc); 621 return; 622 } 623 724 624 async_answer_0(callid, EOK); 725 625 } … … 735 635 log_msg(LVL_DEBUG, "tcp_sock_setsockopt()"); 736 636 async_answer_0(callid, ENOTSUP); 737 }738 739 /** Called when connection state changes. */740 static void tcp_sock_cstate_cb(tcp_conn_t *conn, void *arg)741 {742 tcp_conn_status_t cstatus;743 tcp_sock_lconn_t *lconn = (tcp_sock_lconn_t *)arg;744 tcp_sockdata_t *socket = lconn->socket;745 746 log_msg(LVL_DEBUG, "tcp_sock_cstate_cb()");747 fibril_mutex_lock(&socket->lock);748 assert(conn == lconn->conn);749 750 tcp_uc_status(conn, &cstatus);751 if (cstatus.cstate != st_established) {752 fibril_mutex_unlock(&socket->lock);753 return;754 }755 756 assert_link_not_used(&lconn->ready_list);757 list_append(&lconn->ready_list, &socket->ready);758 759 log_msg(LVL_DEBUG, "tcp_sock_cstate_cb(): notify accept");760 761 /* Push one accept notification to client's queue */762 tcp_sock_notify_aconn(socket->sock_core);763 fibril_mutex_unlock(&socket->lock);764 637 } 765 638
Note:
See TracChangeset
for help on using the changeset viewer.