|
@@ -529,35 +529,59 @@ int tcp_close ( struct tcp_connection *conn ) {
|
529
|
529
|
return tcp_send ( conn, TCP_NOMSG, TCP_NOMSG_LEN );
|
530
|
530
|
}
|
531
|
531
|
|
|
532
|
+/**
|
|
533
|
+ * Bind TCP connection to local port
|
|
534
|
+ *
|
|
535
|
+ * @v conn TCP connection
|
|
536
|
+ * @v local_port Local port, in network byte order
|
|
537
|
+ * @ret rc Return status code
|
|
538
|
+ */
|
|
539
|
+int tcp_bind ( struct tcp_connection *conn, uint16_t local_port ) {
|
|
540
|
+ struct tcp_connection *existing;
|
|
541
|
+
|
|
542
|
+ list_for_each_entry ( existing, &tcp_conns, list ) {
|
|
543
|
+ if ( existing->local_port == local_port )
|
|
544
|
+ return -EADDRINUSE;
|
|
545
|
+ }
|
|
546
|
+ conn->local_port = local_port;
|
|
547
|
+ return 0;
|
|
548
|
+}
|
|
549
|
+
|
532
|
550
|
|
533
|
551
|
/**
|
534
|
552
|
* Listen for a packet
|
535
|
553
|
*
|
536
|
|
- * @v conn TCP connection
|
537
|
|
- * @v port Local port, in network byte order
|
|
554
|
+ * @v conn TCP connection
|
|
555
|
+ * @v local_port Local port, in network byte order
|
538
|
556
|
*
|
539
|
|
- * This function adds the connection to a list of registered tcp connections. If
|
540
|
|
- * the local port is 0, the connection is assigned the lowest available port
|
541
|
|
- * between MIN_TCP_PORT and 65535.
|
|
557
|
+ * This function adds the connection to a list of registered tcp
|
|
558
|
+ * connections. If the local port is 0, the connection is assigned an
|
|
559
|
+ * available port between MIN_TCP_PORT and 65535.
|
542
|
560
|
*/
|
543
|
|
-int tcp_listen ( struct tcp_connection *conn, uint16_t port ) {
|
544
|
|
- struct tcp_connection *cconn;
|
545
|
|
- if ( port != 0 ) {
|
546
|
|
- list_for_each_entry ( cconn, &tcp_conns, list ) {
|
547
|
|
- if ( cconn->local_port == port ) {
|
548
|
|
- DBG ( "Error listening to %d\n",
|
549
|
|
- ntohs ( port ) );
|
550
|
|
- return -EISCONN;
|
551
|
|
- }
|
|
561
|
+int tcp_listen ( struct tcp_connection *conn, uint16_t local_port ) {
|
|
562
|
+ static uint16_t try_port = 1024;
|
|
563
|
+ int rc;
|
|
564
|
+
|
|
565
|
+ /* If no port specified, find the first available port */
|
|
566
|
+ if ( ! local_port ) {
|
|
567
|
+ for ( ; try_port ; try_port++ ) {
|
|
568
|
+ if ( try_port < 1024 )
|
|
569
|
+ continue;
|
|
570
|
+ if ( tcp_listen ( conn, htons ( try_port ) ) == 0 )
|
|
571
|
+ return 0;
|
552
|
572
|
}
|
553
|
|
- /* Add the connection to the list of registered connections */
|
554
|
|
- conn->local_port = port;
|
555
|
|
- list_add ( &conn->list, &tcp_conns );
|
556
|
|
- return 0;
|
|
573
|
+ return -EADDRINUSE;
|
557
|
574
|
}
|
558
|
|
- /* Assigning lowest port not supported */
|
559
|
|
- DBG ( "Assigning lowest port not implemented\n");
|
560
|
|
- return -ENOSYS;
|
|
575
|
+
|
|
576
|
+ /* Attempt bind to local port */
|
|
577
|
+ if ( ( rc = tcp_bind ( conn, local_port ) ) != 0 )
|
|
578
|
+ return rc;
|
|
579
|
+
|
|
580
|
+ /* Add to TCP connection list */
|
|
581
|
+ list_add ( &conn->list, &tcp_conns );
|
|
582
|
+ DBG ( "TCP opened %p on port %d\n", conn, ntohs ( local_port ) );
|
|
583
|
+
|
|
584
|
+ return 0;
|
561
|
585
|
}
|
562
|
586
|
|
563
|
587
|
/**
|