1 /* uipc_socket2.c 4.36 83/05/01 */ 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 16 /* 17 * Primitive routines for operating on sockets and socket buffers 18 */ 19 20 /* 21 * Procedures to manipulate state flags of socket 22 * and do appropriate wakeups. Normal sequence from the 23 * active (originating) side is that soisconnecting() is 24 * called during processing of connect() call, 25 * resulting in an eventual call to soisconnected() if/when the 26 * connection is established. When the connection is torn down 27 * soisdisconnecting() is called during processing of disconnect() call, 28 * and soisdisconnected() is called when the connection to the peer 29 * is totally severed. The semantics of these routines are such that 30 * connectionless protocols can call soisconnected() and soisdisconnected() 31 * only, bypassing the in-progress calls when setting up a ``connection'' 32 * takes no time. 33 * 34 * From the passive side, a socket is created with SO_ACCEPTCONN 35 * creating two queues of sockets: so_q0 for connections in progress 36 * and so_q for connections already made and awaiting user acceptance. 37 * As a protocol is preparing incoming connections, it creates a socket 38 * structure queued on so_q0 by calling sonewconn(). When the connection 39 * is established, soisconnected() is called, and transfers the 40 * socket structure to so_q, making it available to accept(). 41 * 42 * If a SO_ACCEPTCONN socket is closed with sockets on either 43 * so_q0 or so_q, these sockets are dropped. 44 * 45 * If and when higher level protocols are implemented in 46 * the kernel, the wakeups done here will sometimes 47 * be implemented as software-interrupt process scheduling. 48 */ 49 50 soisconnecting(so) 51 struct socket *so; 52 { 53 54 so->so_state &= ~(SS_ISCONNECTED|SS_ISDISCONNECTING); 55 so->so_state |= SS_ISCONNECTING; 56 wakeup((caddr_t)&so->so_timeo); 57 } 58 59 soisconnected(so) 60 struct socket *so; 61 { 62 register struct socket *head = so->so_head; 63 64 if (head) { 65 if (soqremque(so, 0) == 0) 66 panic("soisconnected"); 67 soqinsque(head, so, 1); 68 wakeup((caddr_t)&head->so_timeo); 69 sorwakeup(head); 70 } 71 so->so_state &= ~(SS_ISCONNECTING|SS_ISDISCONNECTING); 72 so->so_state |= SS_ISCONNECTED; 73 wakeup((caddr_t)&so->so_timeo); 74 sorwakeup(so); 75 sowwakeup(so); 76 } 77 78 soisdisconnecting(so) 79 struct socket *so; 80 { 81 82 so->so_state &= ~SS_ISCONNECTING; 83 so->so_state |= (SS_ISDISCONNECTING|SS_CANTRCVMORE|SS_CANTSENDMORE); 84 wakeup((caddr_t)&so->so_timeo); 85 sowwakeup(so); 86 sorwakeup(so); 87 } 88 89 soisdisconnected(so) 90 struct socket *so; 91 { 92 93 so->so_state &= ~(SS_ISCONNECTING|SS_ISCONNECTED|SS_ISDISCONNECTING); 94 so->so_state |= (SS_CANTRCVMORE|SS_CANTSENDMORE); 95 wakeup((caddr_t)&so->so_timeo); 96 sowwakeup(so); 97 sorwakeup(so); 98 } 99 100 /* 101 * When an attempt at a new connection is noted on a socket 102 * which accepts connections, sonewconn is called. If the 103 * connection is possible (subject to space constraints, etc.) 104 * then we allocate a new structure, propoerly linked into the 105 * data structure of the original socket, and return this. 106 */ 107 struct socket * 108 sonewconn(head) 109 register struct socket *head; 110 { 111 register struct socket *so; 112 struct mbuf *m; 113 114 if (head->so_qlen + head->so_q0len > 3 * head->so_qlimit / 2) 115 goto bad; 116 m = m_getclr(M_DONTWAIT, MT_SOCKET); 117 if (m == NULL) 118 goto bad; 119 so = mtod(m, struct socket *); 120 so->so_type = head->so_type; 121 so->so_options = head->so_options &~ SO_ACCEPTCONN; 122 so->so_linger = head->so_linger; 123 so->so_state = head->so_state | SS_NOFDREF; 124 so->so_proto = head->so_proto; 125 so->so_timeo = head->so_timeo; 126 so->so_pgrp = head->so_pgrp; 127 soqinsque(head, so, 0); 128 if ((*so->so_proto->pr_usrreq)(so, PRU_ATTACH, (struct mbuf *)0, 129 (struct mbuf *)0)) { 130 (void) soqremque(so, 0); 131 (void) 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 soreserve(so, sndcc, rcvcc) 328 struct socket *so; 329 int sndcc, rcvcc; 330 { 331 332 if (sbreserve(&so->so_snd, sndcc) == 0) 333 goto bad; 334 if (sbreserve(&so->so_rcv, rcvcc) == 0) 335 goto bad2; 336 return (0); 337 bad2: 338 sbrelease(&so->so_snd); 339 bad: 340 return (ENOBUFS); 341 } 342 343 /* 344 * Allot mbufs to a sockbuf. 345 */ 346 sbreserve(sb, cc) 347 struct sockbuf *sb; 348 { 349 350 /* someday maybe this routine will fail... */ 351 sb->sb_hiwat = cc; 352 /* the 2 implies names can be no more than 1 mbuf each */ 353 sb->sb_mbmax = cc*2; 354 return (1); 355 } 356 357 /* 358 * Free mbufs held by a socket, and reserved mbuf space. 359 */ 360 sbrelease(sb) 361 struct sockbuf *sb; 362 { 363 364 sbflush(sb); 365 sb->sb_hiwat = sb->sb_mbmax = 0; 366 } 367 368 /* 369 * Routines to add (at the end) and remove (from the beginning) 370 * data from a mbuf queue. 371 */ 372 373 /* 374 * Append mbuf queue m to sockbuf sb. 375 */ 376 sbappend(sb, m) 377 register struct mbuf *m; 378 register struct sockbuf *sb; 379 { 380 register struct mbuf *n; 381 382 n = sb->sb_mb; 383 if (n) 384 while (n->m_next) 385 n = n->m_next; 386 while (m) { 387 if (m->m_len == 0 && (int)m->m_act == 0) { 388 m = m_free(m); 389 continue; 390 } 391 if (n && n->m_off <= MMAXOFF && m->m_off <= MMAXOFF && 392 (int)n->m_act == 0 && (int)m->m_act == 0 && 393 (n->m_off + n->m_len + m->m_len) <= MMAXOFF) { 394 bcopy(mtod(m, caddr_t), mtod(n, caddr_t) + n->m_len, 395 (unsigned)m->m_len); 396 n->m_len += m->m_len; 397 sb->sb_cc += m->m_len; 398 m = m_free(m); 399 continue; 400 } 401 sballoc(sb, m); 402 if (n == 0) 403 sb->sb_mb = m; 404 else 405 n->m_next = m; 406 n = m; 407 m = m->m_next; 408 n->m_next = 0; 409 } 410 } 411 412 /* 413 * Append data and address. 414 * Return 0 if no space in sockbuf or if 415 * can't get mbuf to stuff address in. 416 */ 417 sbappendaddr(sb, asa, m0) 418 struct sockbuf *sb; 419 struct sockaddr *asa; 420 struct mbuf *m0; 421 { 422 struct sockaddr *msa; 423 register struct mbuf *m; 424 register int len = sizeof (struct sockaddr); 425 426 m = m0; 427 if (m == 0) 428 panic("sbappendaddr"); 429 for (;;) { 430 len += m->m_len; 431 if (m->m_next == 0) { 432 m->m_act = (struct mbuf *)1; 433 break; 434 } 435 m = m->m_next; 436 } 437 if (len > sbspace(sb)) 438 return (0); 439 m = m_get(M_DONTWAIT, MT_SONAME); 440 if (m == 0) 441 return (0); 442 m->m_len = sizeof (struct sockaddr); 443 msa = mtod(m, struct sockaddr *); 444 *msa = *asa; 445 m->m_act = (struct mbuf *)1; 446 sbappend(sb, m); 447 sbappend(sb, m0); 448 return (1); 449 } 450 451 #ifdef notdef 452 SBCHECK(sb, str) 453 struct sockbuf *sb; 454 char *str; 455 { 456 register int cnt = sb->sb_cc; 457 register int mbcnt = sb->sb_mbcnt; 458 register struct mbuf *m; 459 460 for (m = sb->sb_mb; m; m = m->m_next) { 461 cnt -= m->m_len; 462 mbcnt -= MSIZE; 463 if (m->m_off > MMAXOFF) 464 mbcnt -= CLBYTES; 465 } 466 if (cnt || mbcnt) { 467 printf("cnt %d mbcnt %d\n", cnt, mbcnt); 468 panic(str); 469 } 470 } 471 #endif 472 473 /* 474 * Free all mbufs on a sockbuf mbuf chain. 475 * Check that resource allocations return to 0. 476 */ 477 sbflush(sb) 478 struct sockbuf *sb; 479 { 480 481 if (sb->sb_flags & SB_LOCK) 482 panic("sbflush"); 483 if (sb->sb_cc) 484 sbdrop(sb, sb->sb_cc); 485 if (sb->sb_cc || sb->sb_mbcnt || sb->sb_mb) 486 panic("sbflush 2"); 487 } 488 489 /* 490 * Drop data from (the front of) a sockbuf chain. 491 */ 492 sbdrop(sb, len) 493 register struct sockbuf *sb; 494 register int len; 495 { 496 register struct mbuf *m = sb->sb_mb, *mn; 497 498 while (len > 0) { 499 if (m == 0) 500 panic("sbdrop"); 501 if (m->m_len > len) { 502 m->m_len -= len; 503 m->m_off += len; 504 sb->sb_cc -= len; 505 break; 506 } 507 len -= m->m_len; 508 sbfree(sb, m); 509 MFREE(m, mn); 510 m = mn; 511 } 512 sb->sb_mb = m; 513 } 514