1 /* uipc_socket2.c 4.26 82/10/03 */ 2 3 #include "../h/param.h" 4 #include "../h/systm.h" 5 #include "../h/dir.h" 6 #include "../h/user.h" 7 #include "../h/proc.h" 8 #include "../h/file.h" 9 #include "../h/inode.h" 10 #include "../h/buf.h" 11 #include "../h/mbuf.h" 12 #include "../h/protosw.h" 13 #include "../h/socket.h" 14 #include "../h/socketvar.h" 15 #include "../net/in.h" 16 #include "../net/in_systm.h" 17 18 /* 19 * Primitive routines for operating on sockets and socket buffers 20 */ 21 22 /* 23 * Procedures to manipulate state flags of socket 24 * and do appropriate wakeups. Normal sequence from the 25 * active (originating) side is that soisconnecting() is 26 * called during processing of connect() call, 27 * resulting in an eventual call to soisconnected() if/when the 28 * connection is established. When the connection is torn down 29 * soisdisconnecting() is called during processing of disconnect() call, 30 * and soisdisconnected() is called when the connection to the peer 31 * is totally severed. The semantics of these routines are such that 32 * connectionless protocols can call soisconnected() and soisdisconnected() 33 * only, bypassing the in-progress calls when setting up a ``connection'' 34 * takes no time. 35 * 36 * From the passive side, a socket is created with SO_ACCEPTCONN 37 * creating two queues of sockets: so_q0 for connections in progress 38 * and so_q for connections already made and awaiting user acceptance. 39 * As a protocol is preparing incoming connections, it creates a socket 40 * structure queued on so_q0 by calling sonewconn(). When the connection 41 * is established, soisconnected() is called, and transfers the 42 * socket structure to so_q, making it available to accept(). 43 * 44 * If a SO_ACCEPTCONN socket is closed with sockets on either 45 * so_q0 or so_q, these sockets are dropped. 46 * 47 * If and when higher level protocols are implemented in 48 * the kernel, the wakeups done here will sometimes 49 * be implemented as software-interrupt process scheduling. 50 */ 51 52 soisconnecting(so) 53 struct socket *so; 54 { 55 56 so->so_state &= ~(SS_ISCONNECTED|SS_ISDISCONNECTING); 57 so->so_state |= SS_ISCONNECTING; 58 wakeup((caddr_t)&so->so_timeo); 59 } 60 61 soisconnected(so) 62 struct socket *so; 63 { 64 register struct socket *head = so->so_head; 65 66 if (head) { 67 if (soqremque(so, 0) == 0) 68 panic("soisconnected"); 69 soqinsque(head, so, 1); 70 wakeup((caddr_t)&head->so_timeo); 71 } 72 so->so_state &= ~(SS_ISCONNECTING|SS_ISDISCONNECTING); 73 so->so_state |= SS_ISCONNECTED; 74 wakeup((caddr_t)&so->so_timeo); 75 sorwakeup(so); 76 sowwakeup(so); 77 } 78 79 soisdisconnecting(so) 80 struct socket *so; 81 { 82 83 so->so_state &= ~SS_ISCONNECTING; 84 so->so_state |= (SS_ISDISCONNECTING|SS_CANTRCVMORE|SS_CANTSENDMORE); 85 wakeup((caddr_t)&so->so_timeo); 86 sowwakeup(so); 87 sorwakeup(so); 88 } 89 90 soisdisconnected(so) 91 struct socket *so; 92 { 93 94 so->so_state &= ~(SS_ISCONNECTING|SS_ISCONNECTED|SS_ISDISCONNECTING); 95 so->so_state |= (SS_CANTRCVMORE|SS_CANTSENDMORE); 96 wakeup((caddr_t)&so->so_timeo); 97 sowwakeup(so); 98 sorwakeup(so); 99 } 100 101 /* 102 * When an attempt at a new connection is noted on a socket 103 * which accepts connections, sonewconn is called. If the 104 * connection is possible (subject to space constraints, etc.) 105 * then we allocate a new structure, propoerly linked into the 106 * data structure of the original socket, and return this. 107 */ 108 struct socket * 109 sonewconn(head) 110 register struct socket *head; 111 { 112 register struct socket *so; 113 struct mbuf *m; 114 115 if (head->so_qlen + head->so_q0len > 3 * head->so_qlimit / 2) 116 goto bad; 117 m = m_getclr(M_DONTWAIT); 118 if (m == 0) 119 goto bad; 120 so = mtod(m, struct socket *); 121 so->so_type = head->so_type; 122 so->so_options = head->so_options &~ SO_ACCEPTCONN; 123 so->so_linger = head->so_linger; 124 so->so_state = head->so_state; 125 so->so_proto = head->so_proto; 126 so->so_timeo = head->so_timeo; 127 so->so_pgrp = head->so_pgrp; 128 soqinsque(head, so, 0); 129 if ((*so->so_proto->pr_usrreq)(so, PRU_ATTACH, 0, 0, 0)) { 130 (void) soqremque(so, 0); 131 m_free(m); 132 goto bad; 133 } 134 return (so); 135 bad: 136 return ((struct socket *)0); 137 } 138 139 soqinsque(head, so, q) 140 register struct socket *head, *so; 141 int q; 142 { 143 144 so->so_head = head; 145 if (q == 0) { 146 head->so_q0len++; 147 so->so_q0 = head->so_q0; 148 head->so_q0 = so; 149 } else { 150 head->so_qlen++; 151 so->so_q = head->so_q; 152 head->so_q = so; 153 } 154 } 155 156 soqremque(so, q) 157 register struct socket *so; 158 int q; 159 { 160 register struct socket *head, *prev, *next; 161 162 head = so->so_head; 163 prev = head; 164 for (;;) { 165 next = q ? prev->so_q : prev->so_q0; 166 if (next == so) 167 break; 168 if (next == head) 169 return (0); 170 prev = next; 171 } 172 if (q == 0) { 173 prev->so_q0 = next->so_q0; 174 head->so_q0len--; 175 } else { 176 prev->so_q = next->so_q; 177 head->so_qlen--; 178 } 179 next->so_q0 = next->so_q = 0; 180 next->so_head = 0; 181 return (1); 182 } 183 184 /* 185 * Socantsendmore indicates that no more data will be sent on the 186 * socket; it would normally be applied to a socket when the user 187 * informs the system that no more data is to be sent, by the protocol 188 * code (in case PRU_SHUTDOWN). Socantrcvmore indicates that no more data 189 * will be received, and will normally be applied to the socket by a 190 * protocol when it detects that the peer will send no more data. 191 * Data queued for reading in the socket may yet be read. 192 */ 193 194 socantsendmore(so) 195 struct socket *so; 196 { 197 198 so->so_state |= SS_CANTSENDMORE; 199 sowwakeup(so); 200 } 201 202 socantrcvmore(so) 203 struct socket *so; 204 { 205 206 so->so_state |= SS_CANTRCVMORE; 207 sorwakeup(so); 208 } 209 210 /* 211 * Socket select/wakeup routines. 212 */ 213 214 /* 215 * Interface routine to select() system 216 * call for sockets. 217 */ 218 soselect(so, rw) 219 register struct socket *so; 220 int rw; 221 { 222 int s = splnet(); 223 224 switch (rw) { 225 226 case FREAD: 227 if (soreadable(so)) { 228 splx(s); 229 return (1); 230 } 231 sbselqueue(&so->so_rcv); 232 break; 233 234 case FWRITE: 235 if (sowriteable(so)) { 236 splx(s); 237 return (1); 238 } 239 sbselqueue(&so->so_snd); 240 break; 241 } 242 splx(s); 243 return (0); 244 } 245 246 /* 247 * Queue a process for a select on a socket buffer. 248 */ 249 sbselqueue(sb) 250 struct sockbuf *sb; 251 { 252 register struct proc *p; 253 254 if ((p = sb->sb_sel) && p->p_wchan == (caddr_t)&selwait) 255 sb->sb_flags |= SB_COLL; 256 else 257 sb->sb_sel = u.u_procp; 258 } 259 260 /* 261 * Wait for data to arrive at/drain from a socket buffer. 262 */ 263 sbwait(sb) 264 struct sockbuf *sb; 265 { 266 267 sb->sb_flags |= SB_WAIT; 268 sleep((caddr_t)&sb->sb_cc, PZERO+1); 269 } 270 271 /* 272 * Wakeup processes waiting on a socket buffer. 273 */ 274 sbwakeup(sb) 275 struct sockbuf *sb; 276 { 277 278 if (sb->sb_sel) { 279 selwakeup(sb->sb_sel, sb->sb_flags & SB_COLL); 280 sb->sb_sel = 0; 281 sb->sb_flags &= ~SB_COLL; 282 } 283 if (sb->sb_flags & SB_WAIT) { 284 sb->sb_flags &= ~SB_WAIT; 285 wakeup((caddr_t)&sb->sb_cc); 286 } 287 } 288 289 /* 290 * Socket buffer (struct sockbuf) utility routines. 291 * 292 * Each socket contains two socket buffers: one for sending data and 293 * one for receiving data. Each buffer contains a queue of mbufs, 294 * information about the number of mbufs and amount of data in the 295 * queue, and other fields allowing select() statements and notification 296 * on data availability to be implemented. 297 * 298 * Before using a new socket structure it is first necessary to reserve 299 * buffer space to the socket, by calling sbreserve. This commits 300 * some of the available buffer space in the system buffer pool for the 301 * socket. The space should be released by calling sbrelease when the 302 * socket is destroyed. 303 * 304 * The routine sbappend() is normally called to append new mbufs 305 * to a socket buffer, after checking that adequate space is available 306 * comparing the function spspace() with the amount of data to be added. 307 * Data is normally removed from a socket buffer in a protocol by 308 * first calling m_copy on the socket buffer mbuf chain and sending this 309 * to a peer, and then removing the data from the socket buffer with 310 * sbdrop when the data is acknowledged by the peer (or immediately 311 * in the case of unreliable protocols.) 312 * 313 * Protocols which do not require connections place both source address 314 * and data information in socket buffer queues. The source addresses 315 * are stored in single mbufs after each data item, and are easily found 316 * as the data items are all marked with end of record markers. The 317 * sbappendaddr() routine stores a datum and associated address in 318 * a socket buffer. Note that, unlike sbappend(), this routine checks 319 * for the caller that there will be enough space to store the data. 320 * It fails if there is not enough space, or if it cannot find 321 * a mbuf to store the address in. 322 * 323 * The higher-level routines sosend and soreceive (in socket.c) 324 * also add data to, and remove data from socket buffers repectively. 325 */ 326 327 /* 328 * Allot mbufs to a sockbuf. 329 */ 330 sbreserve(sb, cc) 331 struct sockbuf *sb; 332 { 333 334 /* someday maybe this routine will fail... */ 335 sb->sb_hiwat = cc; 336 sb->sb_mbmax = cc*2; 337 return (1); 338 } 339 340 /* 341 * Free mbufs held by a socket, and reserved mbuf space. 342 */ 343 sbrelease(sb) 344 struct sockbuf *sb; 345 { 346 347 sbflush(sb); 348 sb->sb_hiwat = sb->sb_mbmax = 0; 349 } 350 351 /* 352 * Routines to add (at the end) and remove (from the beginning) 353 * data from a mbuf queue. 354 */ 355 356 /* 357 * Append mbuf queue m to sockbuf sb. 358 */ 359 sbappend(sb, m) 360 register struct mbuf *m; 361 register struct sockbuf *sb; 362 { 363 register struct mbuf *n; 364 365 n = sb->sb_mb; 366 if (n) 367 while (n->m_next) 368 n = n->m_next; 369 while (m) { 370 if (m->m_len == 0 && (int)m->m_act == 0) { 371 m = m_free(m); 372 continue; 373 } 374 if (n && n->m_off <= MMAXOFF && m->m_off <= MMAXOFF && 375 (int)n->m_act == 0 && (int)m->m_act == 0 && 376 (n->m_off + n->m_len + m->m_len) <= MMAXOFF) { 377 bcopy(mtod(m, caddr_t), mtod(n, caddr_t) + n->m_len, 378 (unsigned)m->m_len); 379 n->m_len += m->m_len; 380 sb->sb_cc += m->m_len; 381 m = m_free(m); 382 continue; 383 } 384 sballoc(sb, m); 385 if (n == 0) 386 sb->sb_mb = m; 387 else 388 n->m_next = m; 389 n = m; 390 m = m->m_next; 391 n->m_next = 0; 392 } 393 } 394 395 /* 396 * Append data and address. 397 * Return 0 if no space in sockbuf or if 398 * can't get mbuf to stuff address in. 399 */ 400 sbappendaddr(sb, asa, m0) 401 struct sockbuf *sb; 402 struct sockaddr *asa; 403 struct mbuf *m0; 404 { 405 struct sockaddr *msa; 406 register struct mbuf *m; 407 register int len = sizeof (struct sockaddr); 408 409 m = m0; 410 if (m == 0) 411 panic("sbappendaddr"); 412 for (;;) { 413 len += m->m_len; 414 if (m->m_next == 0) { 415 m->m_act = (struct mbuf *)1; 416 break; 417 } 418 m = m->m_next; 419 } 420 if (len > sbspace(sb)) 421 return (0); 422 m = m_get(M_DONTWAIT); 423 if (m == 0) 424 return (0); 425 m->m_off = MMINOFF; 426 m->m_len = sizeof (struct sockaddr); 427 msa = mtod(m, struct sockaddr *); 428 *msa = *asa; 429 m->m_act = (struct mbuf *)1; 430 sbappend(sb, m); 431 sbappend(sb, m0); 432 return (1); 433 } 434 435 /* 436 * Free all mbufs on a sockbuf mbuf chain. 437 * Check that resource allocations return to 0. 438 */ 439 sbflush(sb) 440 struct sockbuf *sb; 441 { 442 443 if (sb->sb_flags & SB_LOCK) 444 panic("sbflush"); 445 if (sb->sb_cc) 446 sbdrop(sb, sb->sb_cc); 447 if (sb->sb_cc || sb->sb_mbcnt || sb->sb_mb) 448 panic("sbflush 2"); 449 } 450 451 /* 452 * Drop data from (the front of) a sockbuf chain. 453 */ 454 sbdrop(sb, len) 455 register struct sockbuf *sb; 456 register int len; 457 { 458 register struct mbuf *m = sb->sb_mb, *mn; 459 460 while (len > 0) { 461 if (m == 0) 462 panic("sbdrop"); 463 if (m->m_len > len) { 464 m->m_len -= len; 465 m->m_off += len; 466 sb->sb_cc -= len; 467 break; 468 } 469 len -= m->m_len; 470 sbfree(sb, m); 471 MFREE(m, mn); 472 m = mn; 473 } 474 sb->sb_mb = m; 475 } 476