Changeset ae481e0 in mainline
- Timestamp:
- 2011-12-29T14:47:00Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 2943db4
- Parents:
- 827ec41
- Location:
- uspace
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/websrv/websrv.c
r827ec41 rae481e0 49 49 50 50 #define PORT_NUMBER 8080 51 #define BACKLOG_SIZE 3 51 52 52 53 #define WEB_ROOT "/data/web" … … 275 276 } 276 277 277 rc = listen(listen_sd, 1);278 rc = listen(listen_sd, BACKLOG_SIZE); 278 279 if (rc != EOK) { 279 280 printf("Error calling listen() (%d).\n", rc); -
uspace/srv/net/tl/tcp/conn.c
r827ec41 rae481e0 121 121 fibril_condvar_initialize(&conn->cstate_cv); 122 122 123 conn->cstate_cb = NULL; 124 123 125 conn->cstate = st_listen; 124 126 conn->reset = false; … … 243 245 tcp_cstate_t old_state; 244 246 247 log_msg(LVL_DEBUG, "tcp_conn_state_set(%p)", conn); 248 245 249 old_state = conn->cstate; 246 250 conn->cstate = nstate; 247 251 fibril_condvar_broadcast(&conn->cstate_cv); 252 253 /* Run user callback function */ 254 if (conn->cstate_cb != NULL) { 255 log_msg(LVL_DEBUG, "tcp_conn_state_set() - run user CB"); 256 conn->cstate_cb(conn, conn->cstate_cb_arg); 257 } else { 258 log_msg(LVL_DEBUG, "tcp_conn_state_set() - no user CB"); 259 } 248 260 249 261 assert(old_state != st_closed); -
uspace/srv/net/tl/tcp/sock.c
r827ec41 rae481e0 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 -
uspace/srv/net/tl/tcp/tcp_type.h
r827ec41 rae481e0 152 152 } acpass_t; 153 153 154 typedef struct tcp_conn { 154 typedef enum { 155 tcp_open_nonblock = 1 156 } tcp_open_flags_t; 157 158 typedef struct tcp_conn tcp_conn_t; 159 160 /** Connection state change callback function */ 161 typedef void (*tcp_cstate_cb_t)(tcp_conn_t *, void *); 162 163 /** Connection */ 164 struct tcp_conn { 155 165 char *name; 156 166 link_t link; 167 168 /** Connection state change callback function */ 169 tcp_cstate_cb_t cstate_cb; 170 /** Argument to @c cstate_cb */ 171 void *cstate_cb_arg; 157 172 158 173 /** Connection identification (local and foreign socket) */ … … 233 248 /** Initial receive sequence number */ 234 249 uint32_t irs; 235 } tcp_conn_t; 236 237 typedef struct { 238 unsigned dummy; 250 }; 251 252 /** Data returned by Status user call */ 253 typedef struct { 254 /** Connection state */ 255 tcp_cstate_t cstate; 239 256 } tcp_conn_status_t; 240 257 … … 314 331 } tcp_client_t; 315 332 316 typedef struct { 333 typedef struct tcp_sockdata { 334 /** Lock */ 335 fibril_mutex_t lock; 336 /** Socket core */ 337 socket_core_t *sock_core; 317 338 /** Client */ 318 339 tcp_client_t *client; … … 321 342 /** Local address */ 322 343 netaddr_t laddr; 344 /** Backlog size */ 345 int backlog; 346 /** Array of listening connections, @c backlog elements */ 347 struct tcp_sock_lconn **lconn; 348 /** List of connections (from lconn) that are ready to be accepted */ 349 list_t ready; 323 350 } tcp_sockdata_t; 351 352 typedef struct tcp_sock_lconn { 353 tcp_conn_t *conn; 354 tcp_sockdata_t *socket; 355 int index; 356 link_t ready_list; 357 } tcp_sock_lconn_t; 358 324 359 325 360 #endif -
uspace/srv/net/tl/tcp/test.c
r827ec41 rae481e0 62 62 fsock.addr.ipv4 = 0x7f000001; 63 63 printf("S: User open...\n"); 64 tcp_uc_open(&lsock, &fsock, ap_passive, &conn);64 tcp_uc_open(&lsock, &fsock, ap_passive, 0, &conn); 65 65 conn->name = (char *) "S"; 66 66 … … 102 102 async_usleep(1000*1000*3); 103 103 printf("C: User open...\n"); 104 tcp_uc_open(&lsock, &fsock, ap_active, &conn);104 tcp_uc_open(&lsock, &fsock, ap_active, 0, &conn); 105 105 conn->name = (char *) "C"; 106 106 -
uspace/srv/net/tl/tcp/ucall.c
r827ec41 rae481e0 53 53 * @param fsock Foreign socket 54 54 * @param acpass Active/passive 55 * @param oflags Open flags 55 56 * @param conn Connection 56 57 * … … 65 66 */ 66 67 tcp_error_t tcp_uc_open(tcp_sock_t *lsock, tcp_sock_t *fsock, acpass_t acpass, 67 tcp_ conn_t **conn)68 tcp_open_flags_t oflags, tcp_conn_t **conn) 68 69 { 69 70 tcp_conn_t *nconn; 70 71 71 log_msg(LVL_DEBUG, "tcp_uc_open(%p, %p, %s, % p)",72 log_msg(LVL_DEBUG, "tcp_uc_open(%p, %p, %s, %s, %p)", 72 73 lsock, fsock, acpass == ap_active ? "active" : "passive", 73 conn);74 oflags == tcp_open_nonblock ? "nonblock" : "none", conn); 74 75 75 76 nconn = tcp_conn_new(lsock, fsock); … … 79 80 /* Synchronize (initiate) connection */ 80 81 tcp_conn_sync(nconn); 82 } 83 84 if (oflags == tcp_open_nonblock) { 85 *conn = nconn; 86 return TCP_EOK; 81 87 } 82 88 … … 101 107 102 108 *conn = nconn; 109 log_msg(LVL_DEBUG, "tcp_uc_open -> %p", nconn); 103 110 return TCP_EOK; 104 111 } … … 258 265 { 259 266 log_msg(LVL_DEBUG, "tcp_uc_status()"); 267 cstatus->cstate = conn->cstate; 260 268 } 261 269 … … 270 278 log_msg(LVL_DEBUG, "tcp_uc_delete()"); 271 279 tcp_conn_delete(conn); 280 } 281 282 void tcp_uc_set_cstate_cb(tcp_conn_t *conn, tcp_cstate_cb_t cb, void *arg) 283 { 284 log_msg(LVL_DEBUG, "tcp_uc_set_ctate_cb(%p, %p, %p)", 285 conn, cb, arg); 286 287 conn->cstate_cb = cb; 288 conn->cstate_cb_arg = arg; 272 289 } 273 290 -
uspace/srv/net/tl/tcp/ucall.h
r827ec41 rae481e0 42 42 * User calls 43 43 */ 44 extern tcp_error_t tcp_uc_open(tcp_sock_t *, tcp_sock_t *, acpass_t, tcp_conn_t **); 44 extern tcp_error_t tcp_uc_open(tcp_sock_t *, tcp_sock_t *, acpass_t, 45 tcp_open_flags_t, tcp_conn_t **); 45 46 extern tcp_error_t tcp_uc_send(tcp_conn_t *, void *, size_t, xflags_t); 46 47 extern tcp_error_t tcp_uc_receive(tcp_conn_t *, void *, size_t, size_t *, xflags_t *); … … 49 50 extern void tcp_uc_status(tcp_conn_t *, tcp_conn_status_t *); 50 51 extern void tcp_uc_delete(tcp_conn_t *); 52 extern void tcp_uc_set_cstate_cb(tcp_conn_t *, tcp_cstate_cb_t, void *); 51 53 52 54 /*
Note:
See TracChangeset
for help on using the changeset viewer.