throbber
460
`
`Socket Layer
`
`Chapter 15
`
`152--164
`
`7--1 79
`
`It is common for asynchronous events to change the state of a socket. The protocol
`processing layer notifies the socket layer of the change by setting so_error and wak-
`ing any process waiting on the socket. Because of this, the socket layer must always
`examine so_error after waking to see if an error occurred while the process was
`sleeping.
`Associate socket with descriptor
`falloc allocates a descriptor for the new connection; the socket is removed from
`the accept queue by soq~eraque and attached to the £± le structure. Exercise 15.4 dis-
`cusses the call to pan±c.
`Protocol processing
`accept allocates a new mbuf to hold the foreign address and calls soaccept to do
`protocol processing. The allocation and queueing of new sockets created during con-
`nection processing is described in Section 15.12. If the process provided a buffer to
`receive the foreign address, copyout copies the address from nam and the length from
`namelen to the process. If necessary, copyout silently truncates the name to fit in the
`process’s buffer. Finally, the mbuf is released, protocol processing enabled, and accept
`returns.
`Because only one mbuf is allocated for the foreign address, transport addresses
`must fit in one mbuf. Unix domain addresses, which are pathnames in the filesystem
`(up to 1023 bytes in length), may encounter this limit, but there is no problem with the
`16-byte sockadd~_in structure for the Internet domain. The comment on line 170
`indicates that this limitation could be removed by allocating and copying an mbuf
`chain.
`
`soaccept Function
`
`soaccept, shown in Figure 15.27, calls the protocol layer to retrieve the client’s address
`for the new connection.
`
`184 soaccept(so, nam)
`185 struct socket *so;
`186 struct mbuf *nam;
`187 {
`188
`189
`
`int
`int
`
`s = splnet();
`error;
`
`uipc_socket.c
`
`190
`191
`192
`193
`194
`195
`196
`197
`
`if ((so->so_state & SS_NOFDREF) :: 0)
`panic("soaccept: [NOFDREF");
`so->so_state &= -SS_NOFDREF;
`error = (*so->so_proto->pr_usrreq) (so, PRU_ACCEPT,
`(struct mbuf *) 0, nam,
`(struct mbuf *) 0);
`
`splx(s);
`return (error);
`
`Figure 15.27 soaccept function.
`
`uipc_socket.c
`
`WISTRON CORP. EXHIBIT 1013.486
`
`

`

`Section 15.12
`
`sonewconn and soisconnected Functions 461
`
`!84-197
`
`soaccept ensures that the socket is associated with a descriptor and issues the
`PRU_ACCEPT request to the protocol. After pr_usrreq returns, ham contains the name
`of the foreign socket.
`15.12 sonewconn and soisconnected Functions
`
`In Figure 15.26 we saw that accept waits for the protocol layer to process incoming
`connection requests and to make them available through so_q. Figure 15.28 uses TCP
`to illustrate this process.
`
`accept
`
`accept
`
`wait for incomi_ng_ connection request
`
`socket{}
`
`so qO_ ;
`
`socket{}
`
`.: ~onnecdon iI
`
`socket { }
`
`complete
`connection
`
`incoming TCP SYN
`
`send SYN and ACK
`wait forA~K ..... t-
`~
`final ACK of
`TCP handshake
`
`Figure 15.28 Incoming TCP connection processing.
`
`In the upper left corner of Figure 15.28, accept calls tsleep to wait for incoming
`connections. In the lower left, tcp_input processes an incoming TCP SYN by calling
`sonewconn to create a socket for the new connection (Figure 28.7). sonewconn queues
`the socket on so_q0, since the three-way handshake is not yet complete.
`
`WISTRON CORP. EXHIBIT 1013.487
`
`

`

`462
`
`Socket Layer
`
`Chapter 15 .....
`
`Se{
`
`13
`
`13
`
`14
`
`14
`
`15
`
`When the final ACK of the TCP handshake arrives, tcp_±nput calls
`so±seonnected (Figure 29.2), which updates the new socket, moves it from so_q0 to
`so_q, and wakes up any processes that had called accept to wait for incoming con-
`nections.
`The upper right comer of the figure shows the functions we described with Fig-
`ure 15.26. When tsleep returns, accept takes the connection off so_q and issues the
`PRU_ATTACH request. The socket is associated with a new file descriptor and returned
`to the calling process.
`Figure 15.29 shows the sonewconn function.
`
`u ipc_socket 2 .c
`
`123 struct socket *
`124 sonewconn(head, connstatus)
`125 struct socket *head;
`connstatus;
`126 int
`127 {
`128
`129
`
`struct socket *so;
`int soqueue = connstatus ? 1 : 0;
`
`if (head->so_qlen + head->so_q01en > 3 * head->so_qlimit / 2)
`return ((struct socket *) 0);
`MALLOC(so, struct socket *, sizeof(*so), M_SOCKET, M_DONTWAIT) ;
`if (so == NULL)
`return ((struct socket *) 0);
`bzero((caddr_t) so, sizeof(*so));
`so->so_type = head->so_type;
`so->so_options = head->so_options & ~SO_ACCEPTCONN;
`so->so_linger = head->so_linger;
`so->so_state = head->so_state I SS_NOFDREF;
`so->so~roto = head->so_proto;
`so->so_timeo = head->so_timeo;
`so->so~gid = head->so~gid;
`(void) soreserve(so, head->so_snd.sb_hiwat, head->so_rcv.sb_hiwat);
`soqinsque(head, so, soqueue);
`if ((*so->so~roto->pr_usrreq) (so, PRU_ATTACH,
`(struct mbuf *) 0, (struct mbuf *) 0,
`(void} soqremque(so, soqueue);
`(void} free((caddr_t) so, M_SOCKET);
`return ((struct socket *) 0);
`
`(struct mbuf *) 0)) {
`
`}i
`
`f (connstatus) {
`sorwakeup(head);
`wakeup((caddr_t) & head->so_timeo);
`so->so_state I= connstatus;
`
`}r
`
`eturn (so);
`
`Figure 15.29 soneweonn function.
`
`uipc_socket2.c
`
`130
`131
`132
`133
`134
`135
`136
`137
`138
`139
`140
`141
`142
`143
`144
`145
`146
`147
`148
`149
`150
`151
`152
`153
`154
`155
`156
`157 }
`
`123-129
`
`The protocol layer passes head, a pointer to the socket that is accepting the incom-
`ing connection, and connstatus, a flag to indicate the state of the new connection. For
`TCP, connstatus is always 0.
`
`WISTRON CORP. EXHIBIT 1013.488
`
`

`

`sonewconn and soisconnected Functions 463
`
`130--131
`
`132--143
`
`144
`
`145--150
`
`151--157
`
`78--87
`
`so_qlen+ so_q01en >
`
`For TP4, connstatus is always SS_ISCONFIRMING. The connection is implicitly confirmed
`when a process begins reading from or writing to the socket.
`Limit incoming connections
`son~wconn prohibits additional connections when the following inequality is true:
`3 x so_qlimit
`2
`This formula provides a fudge factor for connections that never complete and guaran-
`tees that l isten(fd, 0) allows one connection. See Figure 18.23 in Volume 1 for an
`additional discussion of this formula.
`Allocate new socket
`A new socket structure is allocated and initialized. If the process calls
`setsockopt for the listening socket, the connected socket inherits several socket
`options because so_options, so_linger, so_pgid, and the sb_hiwat values are
`copied into the new socket structure.
`Queue connection
`soqueue was set from connstatus on line 129. The new socket is inserted onto
`so_q0 if soqueue is 0 (e.g., TCP connections) or onto so_q if connstatus is nonzero
`(e.g., TP4 connections).
`Protocol processing
`The PRU_ATTACH request is issued to perform protocol layer processing on the new
`connection. If this fails, the socket is dequeued and discarded, and sonewconn returns
`a null pointer.
`Wakeup processes
`If connstatus is nonzero, any processes sleeping in accept or selecting for read-
`ability on the socket are awakened, connstatus is logically ORed with so_state.
`This code is never executed for TCP connections, since connstatus is always 0 for
`TCP.
`
`Protocols, such as TCP, that put incoming connections on so_q0 first, call
`soisconnected when the connection establishment phase completes. For TCP, this
`happens when the second SYN is ACKed on the connection.
`Figure 15.30 shows sei sconnec ted.
`Queue incomplete connections
`The socket state is changed to show that the connection has completed. When
`soisconnected is’called for incoming connections, (i.e., when the local process is call-
`ing accept), head is nonnull.
`If soqremque returns 1, the socket is queued on so_q and sorwakeup wakes up
`any processes using select to monitor the socket for connection arrival by testing for
`readability. If a process is blocked in accept waiting for the connection, wakeup
`causes the matching t s 1 e ep to return.
`
`WISTRON CORP. EXHIBIT 1013.489
`
`

`

`464
`
`Socket Layer
`
`78 soisconnected(so)
`79 struct socket *so;
`80 {
`81
`
`struct socket *head = so->so_head;
`
`SS_ISDISCONNECTING
`
`so->so_state &= -(SS_ISCONNECTING
`so->so_state I= SS_ISCONNECTED;
`if (head && soqremque(so, 0)) {
`soqinsque(head, so, I);
`sorwakeup(head);
`wakeup((caddr_t) & head->so_timeo);
`] else {
`wakeup((caddr_t) & so->so_timeo);
`sorwakeup(so);
`sowwakeup(so);
`
`82
`83
`84
`85
`86
`87
`88
`89
`90
`91
`92
`93 ]
`
`uipc_socket2.c
`
`] SS_ISCONFIRMING);
`
`]
`
`Figure 15.30 soisconnected function.
`
`uipc_socket2.c
`
`88--93
`
`Wakeup processes waiting for new connection
`If head is null, soqremque is not called since the process initiated the connection
`with the connect system call and the socket is not on a queue. If head is nonnull and
`soqremque returns 0, the socket is already on so_q. This happens with protocols such
`as TP4, which place connections on so_q before they are complete, wakeup awakens
`any process blocked in connect, and sorwakeup and sowwakeup take care of any
`processes that are using select to wait for the connection to complete.
`
`15.13 connect System call
`
`A server process calls the listen and accept system calls to wait for a remote process
`to initiate a connection. If the process wants to initiate a connection itself (i.e., a client),
`it calls connect.
`For connection-oriented protocols such as TCP, connect establishes a connection to
`the specified foreign address. The kernel selects and implicitly binds an address to the
`local socket if the process has not already done so with bind.
`For connectionless protocols such as UDP or ICMP, connect records the foreign
`address for use in sending future datagrams. Any previous foreign address is replaced
`with the new address.
`Figure 15.31 shows the functions called when connect is used for UDP or TCR
`The left side of the figure shows connect processing for connectionless protocols,
`such as UDP. In this case the protocol layer calls soisconnected and the connect
`system call returns immediately.
`The right side of the figure shows connect processing for connection-oriented pro-
`tocols, such as TCP. In this case, the protocol layer begins the connection establishment
`and calls soisconnecting to indicate that the connection will complete some time in
`the future. Unless the socket is nonblocking, soconnect calls tsleep to wait for the
`
`WISTRON CORP. EXHIBIT 1013.490
`
`

`

`G) ;
`
`t
`
`Section 15.13
`
`connect System call
`
`465
`
`_
`
`ECT request
`
`-
`
`TCP beglns three-way
`handshake
`
`~
`
`i
`~
`
`TCP three-way
`handshake completes
`
`....... -T~i~ connection
`establishment
`
`Figure 15.31 connect processing.
`
`connection to complete. For TCP, when the three-way handshake is complete, the
`protocol layer calls soisconnected to mark the socket as connected and then calls
`wakeup to awaken the process and complete the connect system call.
`
`180--188
`
`189--200
`
`201--208
`
`Figure 15.32 shows the connect system call.
`The three arguments to connect (in the connect_args structure) are: s, the
`socket descriptor; name, a pointer to a buffer containing the foreign address; and
`name 1 en, the length of the buffer.
`getsock returns the socket as usual. A connection request may already be pend-
`ing on a nonblocking socket, in which case EALREADY is returned, sockargs copies
`the foreign address from the process into the kernel.
`Start connection processing
`The connection attempt is started by calling soconnec t. If soconnect reports an
`error, connect jumps to bad. If a connection has not yet completed by the time
`soconnect returns and nonblocking I/O is enabled, EINPROGRESS is returned imme-
`diately to avoid waiting for the connection to complete. Since connection establishment
`
`WISTRON CORP. EXHIBIT 1013.491
`
`

`

`Socket Layer
`
`Chapter 15
`
`Se
`
`180 struct connect_args {
`181
`int
`s;
`182
`caddr_t name;
`183
`int
`namelen;
`184 ];
`
`185 connect(p, uap, retval)
`186 struct proc *p;
`187 struct connect_args *uap;
`188 int *retval;
`189 {
`190
`191
`192
`193
`
`struct file *fp;
`struct socket *so;
`struct mbuf *nam;
`int
`error, s;
`
`uipc_syscalls.c
`
`2O
`
`2.1
`
`if (error = getsock(p->p_fd, uap->s, &fp))
`return (error);
`so = (struct socket *) fp->f_data;
`if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING))
`return (EALREADY);
`if (error = sockargs(&nam, uap->name, uap->namelen, MT_SONAME))
`return (error);
`
`error : Soconnect(so, nam);
`if (error)
`goto bad;
`if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING))
`m_freem(nam);
`return (EINPROGRESS);
`
`}s
`
` = splnet();
`while ((so->so_state & SS_ISCONNECTING) && so->so_error =: 0)
`if (error = tsleep((caddr_t) & so->so_timeo, PSOCK I PCATCH,
`netcon, 0))
`
`break;
`if (error == 0) {
`error : so->so_error;
`so->so_error : 0;
`
`}s
`
`plx(s);
`bad:
`so->so_state &= ~SS_ISCONNECTING;
`m_freem(nam);
`if (error == ERESTART)
`error = EINTR;
`return (error);
`
`194
`195
`196
`197
`198
`199
`200
`
`201
`2O2
`203
`204
`205
`206
`207
`208
`209
`210
`211
`212
`213
`214
`215
`216
`217
`218
`219
`220
`221
`222
`223
`224
`
`Figure 15.32 connect system call.
`
`uipc_syscalls.c
`
`WISTRON CORP. EXHIBIT 1013.492
`
`

`

`ler 15
`
`:alls.c
`
`alls.c
`
`Section 15.13
`
`connect System call 467
`
`normally involves exchanging several packets with the remote system, it may take a
`while to complete. Further calls to connect return EALREADY until the connection
`completes. ~.T SCONN is returned when the connection is complete.
`Wait for connection establishment
`The wh±le loop continues until the connection is established or an error occurs.
`splnet prevents connect from missing a wakeup between testing the state of the
`socket and the call to tsleep. After the loop, error contains 0, the error code from
`t s 3_eep, or the error from the socket.
`The SS_TSCONN~.CTING flag is cleared since the connection has completed or the
`attempt has failed. The mbuf containing the foreign address is released and any error is
`returned.
`
`208--21 7
`
`218--224
`
`soconnect Function
`
`This function ensures that the socket is in a valid state for a connection request. If the
`socket is not connected or a connection is not pending, then the connection request is
`always valid. If the socket is already connected or a connection is pending, the new
`connection request is rejected for connection-oriented protocols such as TCP. For con-
`nectionless protocols such as UDP, multiple connection requests are OK but each new
`request replaces the previous foreign address.
`Figure 15.33 shows the soconnee t function.
`
`uipc_socket.c
`
`198 soconnect(so, ham)
`199 struct socket *so;
`200 struct mbuf *nam;
`201 {
`202
`203
`
`int
`int
`
`s;
`error;
`if (so->so_options & SO_ACCEPTCONN)
`return (EOPNOTSUPP);
`s = splnet();
`/*
`* If protocol is connection-based, can only connect once.
`* Otherwise, if connected, try to disconnect first.
`* This allows user to disconnect by connecting to, e.g.,
`* a null address.
`*/
`if (so >so_state & (SS_ISCONNECTED I SS_ISCONNECTING) &&
`((so->so_proto->pr_flags & PR_CONNREQUIRED) I I
`(error = sodisconnect(so))))
`error = EISCONN;
`
`204
`205
`206
`207
`208
`209
`210
`211
`212
`213
`214
`215
`216
`217
`218
`219
`220
`221
`222
`
`else
`
`error : (*so->so_proto->pr_usrreq} (so, PRU_CONNECT,
`(struct mbuf *) 0, ham, (struct mbuf *) 0);
`
`splx(s);
`return (error);
`
`Figure 15.33 soconnect function.
`
`uipc_socket.c
`
`WISTRON CORP. EXHIBIT 1013.493
`
`

`

`468
`
`Socket Layer
`
`Chapter 15
`
`198-222
`
`soconnect returns EOPNOTSUPP if the socket is marked to accept connections,
`since a process cannot initiate connections if listen has already been called for the
`socket. EISCONN is returned if the protocol is connection oriented and a connection has
`already been initiated. For a connectionless protocol, any existing association with a
`foreign address is broken by sodi sconnect.
`The PRU_CONNECT request starts the appropriate protocol processing to establish
`the connection or the association.
`
`Breaking a Connectionless Association
`
`For connectionless protocols, the foreign address associated with a socket can be dis-
`carded by calling connect with an invalid name such as a pointer to a structure filled
`with 0s or a structure with an invalid size. sodisconnect removes a foreign address
`associated with the socket, and PRU_CONNECT returns an error such as EAFNOSUPPORT
`or EADDRNOTAVAIL, leaving the socket with no foreign address. This is a useful,
`although obscure, way of breaking the association between a connectionless socket and
`a foreign address without replacing it.
`
`15.14 shutdown System Call
`
`The shutdown system call, shown in Figure 15.34, closes the write-half, read-half, or
`both halves of a connection. For the read-half, shutdown discards any data the process
`hasn’t yet read and any data that arrives after the call to shutdown. For the write-half,
`shutdown lets the protocol specify the semantics. For TCP, any remaining data will be
`sent followed by a FIN. This is TCP’s half-close feature (Section 18.5 of Volume 1).
`To destroy the socket and release the descriptor, close must be called, close can
`also be called directly without first calling shutdown. As with all descriptors, close is
`called by the kernel for sockets that have not been closed when a process terminates.
`
`550 struct shutdown_args { uipc_syscalls.c
`551 int
`s;
`552
`int
`how;
`553 } ;
`554 shutdown(p, uap, retval)
`555 struct proc *p;
`556 struct shutdown_args *uap;
`557 int
`*retval;
`558 {
`559
`560
`
`struct file *fp;
`int
`error;
`
`561
`562
`563
`564 }
`
`if (error : getsock(p->p_fd, uap->s, &fp))
`return (error);
`return (soshutdown((struct socket *) fp->f_data, uap->how));
`
`Figure 15.34 shutdown system call.
`
`uipc_syscalls.c
`
`WISTRON CORP. EXHIBIT 1013.494
`
`

`

`15
`
`.S,
`le
`is
`a
`
`;h
`
`)r
`;s
`f,
`
`n
`
`.¢
`
`Section 15.14
`
`shutdown System Call 469
`
`550-557
`
`In the shutdown_args structure, s is the socket descriptor and how specifies
`which halves of the connection are to be closed. Figure 15.35 shows the expected values
`for how and how++ (which is used in Figure 15.36).
`
`how
`0
`1
`2
`
`how+ +
`Description
`FREAD
`shut down the read-half of the connection
`FWRITE
`shut down the write-half of the connection
`FREAD/FWRITE shut down both halves of the connection
`
`Figure 15.35 shutdown system call options,
`
`Notice that there is an implicit numerical relationship between how and the constants FREAD
`and FWRITE.
`
`558-564
`
`shutdown is a wrapper function for soshutdown. The socket associated with the
`descriptor is returned by getsock, soshutdown is called, and its value is returned.
`soshutdown and sorflush Functions
`
`The shut down of the read-half of a connection is handled in the socket layer by
`sorflush, and the shut down of the write-half of a connection is processed by the
`PRU_SHUTDOWN request in the protocol layer. The soshutdown function is shown in
`Figure 15.36.
`
`720 soshutdown(so, how)
`721 struct socket *so;
`722 int
`how;
`723 {
`724
`
`struct protosw *pr = so->so~Droto;
`
`uipc_socket.c
`
`725
`726
`727
`728
`729
`730
`731
`732
`
`how++;
`if (how & FREAD)
`sorflush(so);
`if (how & FWRITE)
`return
`(*pr->pr_usrreq) (so, PRU_SHUTDOWN,
`(struct mbuf *) 0, (struct mbuf *)
`O, (struct mbuf *) 0)) ;
`
`return (0);
`
`Figure 15.36 soshutdown function.
`
`uipc_socket, c
`
`720--732
`
`733--747
`
`If the read-half of the socket is being closed, sorflush, shown in Figure 15.37, dis-
`cards the data in the socket’s receive buffer and disables the read-half of the connection.
`If the write-half of the socket is being closed, the PRU_SHUTDOWN request is issued to
`the protocol.
`The process waits for a lock on the receive buffer. Because of SB_NOINTR, sblock
`does not return when an interrupt occurs, splimp blocks network interrupts and
`protocol processing while the socket is modified, since the receive buffer may be
`accessed by the protocol layer as it processes incoming packets.
`
`WISTRON CORP. EXHIBIT 1013.495
`
`

`

`47O
`
`Socket Layer
`
`733 sorflush(so)
`734 struct socket *so;
`735 {
`736
`737
`738
`739
`
`struct sockbuf *sb = &so->so_rcv;
`struct protosw *pr = so->so_proto;
`int
`s;
`struct sockbuf asb;
`
`Chapter 15
`
`uipc_socket.c
`
`740
`741
`742
`743
`744
`745
`746
`747
`
`748
`749
`750
`751
`
`sb->sb_flags ]: SB_NOINTR;
`(void) sblock(sb, M_WAITOK);
`s = splimp();
`socantrcvmore(so);
`sbunlock(sb);
`asb = *sb;
`bzero((caddr_t) sb, sizeof(*sb));
`splx(s);
`
`if (pr->pr_flags & PR_RIGHTS && pr->pr_domain->dom_dispose)
`(*pr >pr_domain->dom_dispose) (asb.sb_mb);
`sbrelease(&asb);
`
`Figure 15.37 sorflush function.
`
`uipc_socket.c
`
`socantrcvmore marks the socket to reject incoming packets. A copy of the
`sockbuf structure is saved in asb to be used after interrupts are restored by splx.
`The original sockbuf structure is cleared by bzero, so that the receive queue appears
`to be empty.
`Release control mbufs
`Some kernel resources may be referenced by control information present in the
`receive queue when shutdown was called. The mbuf chain is still available through
`sb_mb in the copy Of the sockbuf structure.
`If the protocol supports access rights and has registered a dora_dispose function,
`it is called here to release these resources.
`
`748-751
`
`In the Unix domain it is possible to pass descriptors between processes with control messages.
`These messages contain pointers to reference counted data structures. The dora_dispose
`function takes care of discarding the references and the data structures if necessary to avoid
`creating an unreferenced structure and introducing a memory leak in the kernel. For more
`information on passing file descriptors within the Unix domain, see [Stevens 1990] and [Leffier
`et al. 1989].
`
`Any input data pending when shutdown is called is discarded when sbrelease
`releases any mbufs on the receive queue.
`Notice that the shut down of the read-half of the connection is processed entirely by
`the socket layer (Exercise 15.6) and the shut down of the write-half of the connection is
`handled by the protocol through the PRU_SHUTDOWN request. TCP responds to the
`PRU_SHUTDOWN by sending all queued data and then a FIN to close the write-half of the
`TCP connection.
`
`WISTRON CORP. EXHIBIT 1013.496
`
`

`

`Section 15.15
`
`close System Call 471
`
`15.15 close System Call
`
`The close system call works with any type of descriptor. When fd is the last descrip-
`tor that references the object, the object-specific c 1 o s e function is called:
`error = (*fp->f_ops->fo_close) (fp, p) ;
`
`As shown in Figure 15.]3, fp->f_ops->fo_close for a socket is the function
`soo_close.
`
`soo_close Function
`
`This function, shown in Figure 15.38, is a wrapper for the soclose function.
`
`152 soo_close(fp, p)
`153 struct file *fp;
`154 struct proc *p;
`155 {
`156
`
`int
`
`error = 0;
`
`157
`158
`159
`160
`161
`
`if (fp->f_data)
`error : soclose((struct socket *) fp->f_data);
`fp->f_data = 0;
`return (error);
`
`Figure 15.38 soo_close function.
`
`sys_socket.c
`
`sys_socket.c
`
`If a socket structure is associated with the file structure, soclose is called,
`f_data is cleared, and any posted error is returned.
`
`soclose Function
`
`This function aborts any connections that are pending on the socket (i.e., that have not
`yet been accepted by a process), waits for data to be transmitted to the foreign system,
`and releases the data structures that are no longer needed.
`soclose is shown in Figure 15.39.
`Discard pending connections
`If the socket was accepting connections, soc!ose traverses the two connection
`queues and calls soabort for each pending connection. If the protocol control block is
`null, the protocol has already been detached from the socket and s oc lose jumps to the
`cleanup code at d±scard.
`
`129--141
`
`soabort issues the PRU_ABORT request to the socket’s protocol and returns the result.
`soabort is not shown in this text. Figures 23.38 and 30.7 discuss how UDP and TCP handle
`this request.
`
`WISTRON CORP. EXHIBIT 1013.497
`
`

`

`472
`
`Socket Layer
`
`129 soclose(so)
`130 struct socket *so;
`131 {
`132
`133
`
`int
`int
`
`s : splnet();
`error = 0;
`
`Chapter 15
`
`uipc_socket.c
`
`/* conservative */
`
`if
`
`so->so_options & SO_ACCEPTCONN) {
`while (so->so_q0)
`(void) soabort(so->so_q0);
`while (so->so_q)
`(void) soabort(so->so_q);
`
`]i
`
`f (so->so_pcb == 0)
`goto discard;
`if (so->so_state & SS_ISCONNECTED) {
`if ((so->so_state & SS_ISDISCONNECTING) == 0) {
`error = sodisconnect(so);
`if (error)
`goto drop;
`
`}i
`
`f (so->so_options & SO_LINGER) {
`if ((so->so_state & SS_ISDISCONNECTING) &&
`(so->so_state & SS_NBIO))
`goto drop;
`while (so >so_state & SS_ISCONNECTED)
`if (error = tsleep((caddr_t) & so->so_timeo,
`PSOCK 1 PCATCH, netcls, so->so_linger)
`
`break;
`
`}
`
`}
`drop:
`if (so->so_pcb) {
`error2 :
`int
`(*so->so_proto->pr_usrreq) (so, PRU_DETACH,
`(struct mbuf *) 0, (struct mbuf *) 0, (struct mbuf *) 0)
`if (error == 0)
`error = error2;
`
`}
`discard:
`if (so->so_state & SS_NOFDREF)
`panic("soclose: NOFDREF");
`so->so_state [= SS_NOFDREF;
`sofree(so);
`splx(s);
`return (error);
`
`Figure 15.39 soclose function.
`
`uipc_socket.c
`
`134
`135
`136
`137
`138
`139
`140
`141
`142
`143
`144
`145
`146
`147
`148
`149
`150
`151
`152
`153
`154
`155
`156
`157
`158
`159
`160
`161
`162
`163
`164
`165
`166
`167
`168
`169
`170
`171
`172
`173 }
`
`WISTRON CORP. EXHIBIT 1013.498
`
`

`

`Section 15.15
`
`close System Call 473
`
`142-157
`
`Break established connection or association
`If the socket is not connected, execution continues at drop; otherwise the socket
`must be disconnected from its peer. If a disconnect is not in progress, sodisconnect
`starts the disconnection process. If the SO_LINGER socket option is set, soclose may
`need to wait for the disconnect to complete before returning. A nonblocking socket
`never waits for a disconnect to complete, so soclose jumps immediately to drop in
`that case. Otherwise, the connection termination is in progress and the SO_LINGER
`option indicates that soclose must wait some time for it to complete. The whi le loop
`continues until the disconnect completes, the linger time (so_l inger) expires, or a sig-
`nal is delivered to the process.
`
`158-173
`
`If the linger time is set to 0, tsleep returns only when the disconnect completes (perhaps
`because of an error) or a signal is delivered.
`Release data structures
`If the socket still has an attached protocol, the PRU_DETACH request breaks the con-
`nection between this socket and the protocol. Finally the socket is marked as not having
`an associated file descriptor, which allows s o free to release the socket.
`The sofree function is shown in Figure 15.40.
`
`ll0"sofree(so)
`iii struct socket *so;
`112 {
`
`uipc_socket.c
`
`113
`114
`115
`116
`117
`118
`119
`120
`121
`122
`123 }
`
`if (so->so_pcb [I (so->so_state & SS_NOFDREF) == 0)
`return;
`if (so->so_head)
`if (!soqremque(so, 0) && !soqremque(so, i))
`panic("sofree dq");
`so->so_head = 0;
`
`}
`sbrelease(&so->so_snd);
`sorflush(so) ;
`FREE(so, M_SOCKET);
`
`Figure 15.40 sofree function.
`
`uipc_socket.c
`
`110--114
`
`115--119
`
`Return if socket still in use
`If a protocol is still associated with the socket, or if the socket is still associated with
`a descriptor, sofree returns immediately.
`Remove from connection queues
`If the socket is on a connection queue (so_head is nonnull), soqremque is called
`to remove the socket. An attempt is made to remove the socket from the incomplete
`connection queue and if this fails, then from the completed connection queue. One of
`the removals must succeed or the kernel panics, since so_head was nonnull, so_head
`is cleared.
`
`WISTRON CORP. EXHIBIT 1013.499
`
`

`

`474
`
`Socket Layer
`
`Chapter 15
`
`:20-:23
`
`Discard send and receive queues
`sbrelease discards any buffers in the send queue and sorflush discards any
`buffers in the receive queue. Finally, the socket itself is released.
`
`15.16 Summary
`
`In this chapter we looked at all the system calls related to network operations. The sys-
`tem call mechanism was described, and we traced the calls until they entered the proto-
`col processing layer through the pr_usrreq function.
`While looking at the socket layer, we avoided any discussion of address formats,
`protocol semantics, or protocol implementations. In the upcoming chapters we tie
`together the link-layer processing and socket-layer processing by looking in detail at the
`implementation of the Internet protocols in the protocol processing layer.
`
`Exercises
`15.1 How can a process without superuser privileges gain access to a socket created by a super-
`user process?
`15.2 How can a process determine if the sockaddr buffer it provides to accept was too small
`to hold the foreign address returned by the call?
`15.3 A feature proposed for IPv6 sockets is to have accept and recvfrom return a source
`route as an array of 128-bit IPv6 addresses instead of a single peer address. Since the array
`will not fit in a single mbuf, modify accept and recvfrom to handle an mbuf chain from
`the protocol layer instead of a single mbuf. Will the existing code work if the protocol
`layer returns the array in an mbuf cluster instead of a chain of mbufs?
`15.4 Why is panic called when soqrernque returns a null pointer in Figure 15.26?
`15.5 Why does sorflush make a copy of the receive buffer?
`15.6 What happens when additional data is received after sorflush has zeroed the socket’s
`receive buffer? Read Chapter 16 before attempting this exercise.
`
`WISTRON CORP. EXHIBIT 1013.500
`
`

`

`Socket I/0
`
`16.1
`
`Introduction
`
`In this chapter we discuss the system calls that read and write data on a network con-
`nection. The chapter is divided into three parts.
`The first part covers the four system calls for sending data: wr±te, wr±tev,
`senc]to, and sendmsg. The second part covers the four system calls for receiving data:
`read, ready, recvfrom, and recvmsg. The third part of the chapter covers the
`select system call, which provides a standard way to monitor the status of descriptors
`in general and sockets in particular.
`The core of the socket layer is the sosend and soreceive functions. They handle
`all I/O between the socket layer and the protocol layer. As we’ll see, the semantics of
`the various types of protocols overlap in these functions, making the functions long and
`complex.
`
`16.2
`
`Code Introduction
`
`The three headers and four C files listed in Figure 16.1 are covered in this chapter.
`
`Global
`
`Variables
`
`The first two global variables shown in Figure 16.2 are used by the se]_ect system call.
`The third global variable controls the amount of memory allocated to a socket.
`
`475
`
`WISTRON CORP. EXHIBIT 1013.501
`
`

`

`476
`
`Socket I/O
`
`Chapter 16
`
`File
`sys/s o eke t. h
`sys/socketvar, h
`sys / ui o. h
`kern/uipc_syscalls, c
`kern/uipc_socket, c
`kern/sys_generic, c
`kern / sys_s ocke t. c
`
`Description
`structures and macro for sockets API
`socket structure and macros
`u i o structure definition
`socket system calls
`socket layer processing
`select system call
`s e I ec t processing for sockets
`
`Figure 16.1 Files discussed in this chapter.
`
`Datatype
`Variable
`wait channel for select
`int
`selwai t
`nselcol i int flag used to avoid race conditions in select
`sb max u_l ong maximum number of bytes to a11ocate for a socket receive or send buffer
`
`Description
`
`Figure 16.2 Global variables introduced in this chapter.
`
`16.3
`
`Socket Buffers
`
`Section 15.3 showed that each socket has an associated send and receive buffer. The
`sockbuf structure definition from Figure 15.5 is repeated in Figure 16.3.
`
`72
`73
`74
`75
`76
`77
`78
`79
`80
`81
`82
`
`struct sockbuf {
`u_long
`sb_cc;
`u_long
`sb_hiwat;
`u_long
`sb_mbcnt;
`u_long sb_mbmax;
`long
`sb_lowat;
`struct mbuf *sb_mb;
`struct selinfo sb_sel;
`sb_flags;
`short
`short
`sb_timeo;
`} so_rcv, so_snd;
`
`/* actual chars in buffer */
`/* max actual char count */
`/* chars of mbufs used */
`/* max chars of mbufs to use */
`/* low water mark */
`/* the mbuf chain */
`/* process selecting read/write */
`/* Figure 16.5 */
`/* timeout for read/write */
`
`socketvar.h
`
`socketvar.h
`
`Figure 16.3 sockbuf structure.
`
`72--78
`
`Each buffer contains control information as well as pointers to data stored in mbuf
`chains, sb mb points to the first mbuf in the chain, and sb_cc is the total number of
`data bytes contained within the mbufs, sb_hiwat and sb_lowat regulate the socket
`flow control algorithms, sb_mbcnt is the total amount of memory allocated to the
`mbufs in the buffer.
`Recall that each mbuf may store from 0 to 2048 bytes of data (if an external cluster is
`used), sb_mbmax is an upper bound on the amount of memory to be allocated as
`
`WISTRON CORP. EXHIBIT 1013.502
`
`

`

`Section 16.3
`
`Socket Buffers 477
`
`mbufs for each socket buffer. Default limits are specified by each protocol when the
`PRU_ATTACH request is issued by the socket system call. The high-water and low-
`water marks may be modified by the process as long as the kernel-enforced hard limit
`of 262,144 bytes per socket buffer (sb_max) is not exceeded. The buffering algorithms
`are described in Sections 16.7 and 16.12. Figure 16.4 shows the default settings for the
`Internet protocols.
`
`Protocol
`
`UDP
`TCP
`raw IP
`ICMP
`IGMP
`
`sb_hiwat
`9 x 1024
`8 x 1024
`
`s o_snd
`sb_lowat
`2048 (ignored)
`2048
`
`sb_mbraax
`2 x sb_hiwat
`2 x sb_hiwat
`
`sb_hiwat
`40 x (1024 + 16)
`8 x I024
`
`s o_r cv
`sb lowat
`1
`1
`
`sb mbmax
`2 x sb_hiwat
`2xsb hiwat
`
`8 x 1024
`
`2048 (ignored)
`
`2 x sb_hiwat
`
`8 x 1024
`
`1
`
`2 x sb_hiwat
`
`Figure 16.4 Default socket buffer limits for the Internet protocols.
`
`Since the source address of each incoming UDP datagram is queued with the data
`(Section 23.8), the default UDP value for sb_hiwat is set to accommodate 40 1K data.-
`grams and thei

This document is available on Docket Alarm but you must sign up to view it.


Or .

Accessing this document will incur an additional charge of $.

After purchase, you can access this document again without charge.

Accept $ Charge
throbber

Still Working On It

This document is taking longer than usual to download. This can happen if we need to contact the court directly to obtain the document and their servers are running slowly.

Give it another minute or two to complete, and then try the refresh button.

throbber

A few More Minutes ... Still Working

It can take up to 5 minutes for us to download a document if the court servers are running slowly.

Thank you for your continued patience.

This document could not be displayed.

We could not find this document within its docket. Please go back to the docket page and check the link. If that does not work, go back to the docket and refresh it to pull the newest information.

Your account does not support viewing this document.

You need a Paid Account to view this document. Click here to change your account type.

Your account does not support viewing this document.

Set your membership status to view this document.

With a Docket Alarm membership, you'll get a whole lot more, including:

  • Up-to-date information for this case.
  • Email alerts whenever there is an update.
  • Full text search for other cases.
  • Get email alerts whenever a new case matches your search.

Become a Member

One Moment Please

The filing “” is large (MB) and is being downloaded.

Please refresh this page in a few minutes to see if the filing has been downloaded. The filing will also be emailed to you when the download completes.

Your document is on its way!

If you do not receive the document in five minutes, contact support at support@docketalarm.com.

Sealed Document

We are unable to display this document, it may be under a court ordered seal.

If you have proper credentials to access the file, you may proceed directly to the court's system using your government issued username and password.


Access Government Site

We are redirecting you
to a mobile optimized page.





Document Unreadable or Corrupt

Refresh this Document
Go to the Docket

We are unable to display this document.

Refresh this Document
Go to the Docket