Changeset ecf823a in mainline for uspace/srv/net/tl/tcp/sock.c
- Timestamp:
- 2011-12-31T10:01:19Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 96cd5b4
- Parents:
- 3819ce5 (diff), 852052d (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/net/tl/tcp/sock.c
r3819ce5 recf823a 52 52 #define FRAGMENT_SIZE 1024 53 53 54 #define MAX_BACKLOG 128 55 54 56 /** Free ports pool start. */ 55 57 #define TCP_FREE_PORTS_START 1025 … … 60 62 static int last_used_port = TCP_FREE_PORTS_START - 1; 61 63 static socket_ports_t gsock; 64 65 static void tcp_sock_cstate_cb(tcp_conn_t *conn, void *arg); 62 66 63 67 void tcp_sock_init(void) … … 95 99 { 96 100 tcp_sockdata_t *sock; 101 socket_core_t *sock_core; 97 102 int sock_id; 98 103 int rc; … … 106 111 } 107 112 113 fibril_mutex_initialize(&sock->lock); 108 114 sock->client = client; 109 115 sock->laddr.ipv4 = TCP_IPV4_ANY; 116 sock->lconn = NULL; 117 sock->backlog = 0; 118 list_initialize(&sock->ready); 110 119 111 120 sock_id = SOCKET_GET_SOCKET_ID(call); … … 115 124 return; 116 125 } 126 127 sock_core = socket_cores_find(&client->sockets, sock_id); 128 assert(sock_core != NULL); 129 sock->sock_core = sock_core; 117 130 118 131 refresh_answer(&answer, NULL); … … 167 180 socket_core_t *sock_core; 168 181 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; 169 188 170 189 log_msg(LVL_DEBUG, "tcp_sock_listen()"); … … 177 196 return; 178 197 } 198 199 if (backlog > MAX_BACKLOG) 200 backlog = MAX_BACKLOG; 179 201 180 202 sock_core = socket_cores_find(&client->sockets, socket_id); … … 187 209 188 210 /* 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. 211 * Prepare @c backlog listening connections. 196 212 */ 197 (void)backlog; 198 (void)socket; 199 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); 200 261 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);204 262 } 205 263 … … 248 306 } 249 307 308 fibril_mutex_lock(&socket->lock); 309 250 310 if (socket->laddr.ipv4 == TCP_IPV4_ANY) { 251 311 /* Find route to determine local IP address. */ … … 254 314 (void **)&phdr, &phdr_len); 255 315 if (rc != EOK) { 316 fibril_mutex_unlock(&socket->lock); 256 317 async_answer_0(callid, rc); 257 318 log_msg(LVL_DEBUG, "tcp_transmit_connect: Failed to find route."); … … 269 330 fsocket.port = uint16_t_be2host(addr->sin_port); 270 331 271 trc = tcp_uc_open(&lsocket, &fsocket, ap_active, &socket->conn);332 trc = tcp_uc_open(&lsocket, &fsocket, ap_active, 0, &socket->conn); 272 333 273 334 if (socket->conn != NULL) 274 335 socket->conn->name = (char *)"C"; 336 337 fibril_mutex_unlock(&socket->lock); 275 338 276 339 switch (trc) { … … 305 368 tcp_sock_t fsocket; 306 369 tcp_conn_t *conn; 370 tcp_conn_t *rconn; 371 tcp_sock_lconn_t *lconn; 307 372 int rc; 308 373 … … 319 384 320 385 socket = (tcp_sockdata_t *)sock_core->specific_data; 386 fibril_mutex_lock(&socket->lock); 321 387 322 388 log_msg(LVL_DEBUG, " - verify socket->conn"); 323 389 if (socket->conn != NULL) { 390 fibril_mutex_unlock(&socket->lock); 324 391 async_answer_0(callid, EINVAL); 325 392 return; 326 393 } 327 394 328 log_msg(LVL_DEBUG, " - open connection"); 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 */ 329 409 330 410 lsocket.addr.ipv4 = TCP_IPV4_ANY; … … 333 413 fsocket.port = TCP_PORT_ANY; 334 414 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 } 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 */ 357 432 358 433 log_msg(LVL_DEBUG, "tcp_sock_accept(): allocate asocket\n"); 359 434 asocket = calloc(sizeof(tcp_sockdata_t), 1); 360 435 if (asocket == NULL) { 436 fibril_mutex_unlock(&socket->lock); 361 437 async_answer_0(callid, ENOMEM); 362 438 return; 363 439 } 364 440 441 fibril_mutex_initialize(&asocket->lock); 365 442 asocket->client = client; 366 443 asocket->conn = conn; … … 369 446 rc = socket_create(&client->sockets, client->sess, asocket, &asock_id); 370 447 if (rc != EOK) { 448 fibril_mutex_unlock(&socket->lock); 371 449 async_answer_0(callid, rc); 372 450 return; … … 385 463 answer_call(callid, asock_core->socket_id, &answer, 3); 386 464 387 /* Push one accept notification to client's queue */388 tcp_sock_notify_aconn(sock_core);389 390 465 /* Push one fragment notification to client's queue */ 466 log_msg(LVL_DEBUG, "tcp_sock_accept(): notify data\n"); 391 467 tcp_sock_notify_data(asock_core); 392 log_msg(LVL_DEBUG, "tcp_sock_accept(): notify aconn\n");468 fibril_mutex_unlock(&socket->lock); 393 469 } 394 470 … … 419 495 420 496 socket = (tcp_sockdata_t *)sock_core->specific_data; 497 fibril_mutex_lock(&socket->lock); 498 421 499 if (socket->conn == NULL) { 500 fibril_mutex_unlock(&socket->lock); 422 501 async_answer_0(callid, ENOTCONN); 423 502 return; … … 426 505 for (index = 0; index < fragments; index++) { 427 506 if (!async_data_write_receive(&wcallid, &length)) { 507 fibril_mutex_unlock(&socket->lock); 428 508 async_answer_0(callid, EINVAL); 429 509 return; … … 435 515 rc = async_data_write_finalize(wcallid, buffer, length); 436 516 if (rc != EOK) { 517 fibril_mutex_unlock(&socket->lock); 437 518 async_answer_0(callid, rc); 438 519 return; … … 459 540 460 541 if (rc != EOK) { 542 fibril_mutex_unlock(&socket->lock); 461 543 async_answer_0(callid, rc); 462 544 return; … … 467 549 SOCKET_SET_DATA_FRAGMENT_SIZE(answer, FRAGMENT_SIZE); 468 550 answer_call(callid, EOK, &answer, 2); 551 fibril_mutex_unlock(&socket->lock); 469 552 } 470 553 … … 504 587 505 588 socket = (tcp_sockdata_t *)sock_core->specific_data; 589 fibril_mutex_lock(&socket->lock); 590 506 591 if (socket->conn == NULL) { 592 fibril_mutex_unlock(&socket->lock); 507 593 async_answer_0(callid, ENOTCONN); 508 594 return; … … 532 618 log_msg(LVL_DEBUG, "**** tcp_uc_receive -> %d", rc); 533 619 if (rc != EOK) { 620 fibril_mutex_unlock(&socket->lock); 534 621 async_answer_0(callid, rc); 535 622 return; … … 545 632 log_msg(LVL_DEBUG, "addr read receive"); 546 633 if (!async_data_read_receive(&rcallid, &addr_length)) { 634 fibril_mutex_unlock(&socket->lock); 547 635 async_answer_0(callid, EINVAL); 548 636 return; … … 555 643 rc = async_data_read_finalize(rcallid, &addr, addr_length); 556 644 if (rc != EOK) { 645 fibril_mutex_unlock(&socket->lock); 557 646 async_answer_0(callid, EINVAL); 558 647 return; … … 562 651 log_msg(LVL_DEBUG, "data read receive"); 563 652 if (!async_data_read_receive(&rcallid, &length)) { 653 fibril_mutex_unlock(&socket->lock); 564 654 async_answer_0(callid, EINVAL); 565 655 return; … … 580 670 /* Push one fragment notification to client's queue */ 581 671 tcp_sock_notify_data(sock_core); 672 fibril_mutex_unlock(&socket->lock); 582 673 } 583 674 … … 603 694 604 695 socket = (tcp_sockdata_t *)sock_core->specific_data; 696 fibril_mutex_lock(&socket->lock); 605 697 606 698 if (socket->conn != NULL) { 607 699 trc = tcp_uc_close(socket->conn); 608 700 if (trc != TCP_EOK && trc != TCP_ENOTEXIST) { 701 fibril_mutex_unlock(&socket->lock); 609 702 async_answer_0(callid, EBADF); 610 703 return; … … 623 716 tcp_free_sock_data); 624 717 if (rc != EOK) { 718 fibril_mutex_unlock(&socket->lock); 625 719 async_answer_0(callid, rc); 626 720 return; 627 721 } 628 722 723 fibril_mutex_unlock(&socket->lock); 629 724 async_answer_0(callid, EOK); 630 725 } … … 640 735 log_msg(LVL_DEBUG, "tcp_sock_setsockopt()"); 641 736 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); 642 764 } 643 765
Note:
See TracChangeset
for help on using the changeset viewer.