This source file includes following definitions.
- nfs_connect
- nfs_reconnect
- nfs_disconnect
- nfs_send
- nfs_receive
- nfs_reply
- nfs_request
- nfs_rephead
- nfs_timer
- nfs_sigintr
- nfs_sndlock
- nfs_sndunlock
- nfs_rcvlock
- nfs_rcvunlock
- nfs_realign_fixup
- nfs_realign
- nfs_getreq
- nfs_msg
- nfsrv_rcv
- nfsrv_getstream
- nfsrv_dorec
- nfsrv_wakenfsd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42 #include <sys/param.h>
43 #include <sys/systm.h>
44 #include <sys/proc.h>
45 #include <sys/mount.h>
46 #include <sys/kernel.h>
47 #include <sys/mbuf.h>
48 #include <sys/vnode.h>
49 #include <sys/domain.h>
50 #include <sys/protosw.h>
51 #include <sys/socket.h>
52 #include <sys/socketvar.h>
53 #include <sys/syslog.h>
54 #include <sys/tprintf.h>
55 #include <sys/namei.h>
56
57 #include <netinet/in.h>
58 #include <netinet/tcp.h>
59
60 #include <nfs/rpcv2.h>
61 #include <nfs/nfsproto.h>
62 #include <nfs/nfs.h>
63 #include <nfs/xdr_subs.h>
64 #include <nfs/nfsm_subs.h>
65 #include <nfs/nfsmount.h>
66 #include <nfs/nfsnode.h>
67 #include <nfs/nfsrtt.h>
68 #include <nfs/nfs_var.h>
69
70 #define TRUE 1
71 #define FALSE 0
72
73
74
75
76
77
78
79
80
81
82
83
84
85 #define NFS_RTO(n, t) \
86 ((t) == 0 ? (n)->nm_timeo : \
87 ((t) < 3 ? \
88 (((((n)->nm_srtt[t-1] + 3) >> 2) + (n)->nm_sdrtt[t-1] + 1) >> 1) : \
89 ((((n)->nm_srtt[t-1] + 7) >> 3) + (n)->nm_sdrtt[t-1] + 1)))
90 #define NFS_SRTT(r) (r)->r_nmp->nm_srtt[proct[(r)->r_procnum] - 1]
91 #define NFS_SDRTT(r) (r)->r_nmp->nm_sdrtt[proct[(r)->r_procnum] - 1]
92
93
94
95 extern u_int32_t rpc_reply, rpc_msgdenied, rpc_mismatch, rpc_vers,
96 rpc_auth_unix, rpc_msgaccepted, rpc_call, rpc_autherr,
97 rpc_auth_kerb;
98 extern u_int32_t nfs_prog;
99 extern struct nfsstats nfsstats;
100 extern int nfsv3_procid[NFS_NPROCS];
101 extern int nfs_ticks;
102
103
104
105
106
107
108
109
110
111 static int proct[NFS_NPROCS] = {
112 0, 1, 0, 2, 1, 3, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0,
113 0, 0, 0,
114 };
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129 #define NFS_CWNDSCALE 256
130 #define NFS_MAXCWND (NFS_CWNDSCALE * 32)
131 static int nfs_backoff[8] = { 2, 4, 8, 16, 32, 64, 128, 256, };
132 int nfsrtton = 0;
133 struct nfsrtt nfsrtt;
134
135 void nfs_realign(struct mbuf **, int);
136 void nfs_realign_fixup(struct mbuf *, struct mbuf *, unsigned int *);
137 unsigned int nfs_realign_test = 0;
138 unsigned int nfs_realign_count = 0;
139
140 struct nfsreqhead nfs_reqq;
141
142
143
144
145
146 int
147 nfs_connect(nmp, rep)
148 struct nfsmount *nmp;
149 struct nfsreq *rep;
150 {
151 struct socket *so;
152 int s, error, rcvreserve, sndreserve;
153 struct sockaddr *saddr;
154 struct sockaddr_in *sin;
155 struct mbuf *m;
156
157 nmp->nm_so = (struct socket *)0;
158 saddr = mtod(nmp->nm_nam, struct sockaddr *);
159 error = socreate(saddr->sa_family, &nmp->nm_so, nmp->nm_sotype,
160 nmp->nm_soproto);
161 if (error)
162 goto bad;
163 so = nmp->nm_so;
164 nmp->nm_soflags = so->so_proto->pr_flags;
165
166
167
168
169
170
171 if (saddr->sa_family == AF_INET) {
172 struct mbuf *mopt;
173 int *ip;
174
175 MGET(mopt, M_WAIT, MT_SOOPTS);
176 mopt->m_len = sizeof(int);
177 ip = mtod(mopt, int *);
178 *ip = IP_PORTRANGE_LOW;
179 error = sosetopt(so, IPPROTO_IP, IP_PORTRANGE, mopt);
180 if (error)
181 goto bad;
182
183 MGET(m, M_WAIT, MT_SONAME);
184 sin = mtod(m, struct sockaddr_in *);
185 sin->sin_len = m->m_len = sizeof (struct sockaddr_in);
186 sin->sin_family = AF_INET;
187 sin->sin_addr.s_addr = INADDR_ANY;
188 sin->sin_port = htons(0);
189 error = sobind(so, m);
190 m_freem(m);
191 if (error)
192 goto bad;
193
194 MGET(mopt, M_WAIT, MT_SOOPTS);
195 mopt->m_len = sizeof(int);
196 ip = mtod(mopt, int *);
197 *ip = IP_PORTRANGE_DEFAULT;
198 error = sosetopt(so, IPPROTO_IP, IP_PORTRANGE, mopt);
199 if (error)
200 goto bad;
201 }
202
203
204
205
206
207 if (nmp->nm_flag & NFSMNT_NOCONN) {
208 if (nmp->nm_soflags & PR_CONNREQUIRED) {
209 error = ENOTCONN;
210 goto bad;
211 }
212 } else {
213 error = soconnect(so, nmp->nm_nam);
214 if (error)
215 goto bad;
216
217
218
219
220
221
222 s = splsoftnet();
223 while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0) {
224 (void) tsleep((caddr_t)&so->so_timeo, PSOCK,
225 "nfscon", 2 * hz);
226 if ((so->so_state & SS_ISCONNECTING) &&
227 so->so_error == 0 && rep &&
228 (error = nfs_sigintr(nmp, rep, rep->r_procp)) != 0){
229 so->so_state &= ~SS_ISCONNECTING;
230 splx(s);
231 goto bad;
232 }
233 }
234 if (so->so_error) {
235 error = so->so_error;
236 so->so_error = 0;
237 splx(s);
238 goto bad;
239 }
240 splx(s);
241 }
242
243
244
245
246 so->so_rcv.sb_timeo = (5 * hz);
247 if (nmp->nm_flag & (NFSMNT_SOFT | NFSMNT_INT))
248 so->so_snd.sb_timeo = (5 * hz);
249 else
250 so->so_snd.sb_timeo = 0;
251 if (nmp->nm_sotype == SOCK_DGRAM) {
252 sndreserve = nmp->nm_wsize + NFS_MAXPKTHDR;
253 rcvreserve = max(nmp->nm_rsize, nmp->nm_readdirsize) +
254 NFS_MAXPKTHDR;
255 } else if (nmp->nm_sotype == SOCK_SEQPACKET) {
256 sndreserve = (nmp->nm_wsize + NFS_MAXPKTHDR) * 2;
257 rcvreserve = (max(nmp->nm_rsize, nmp->nm_readdirsize) +
258 NFS_MAXPKTHDR) * 2;
259 } else {
260 if (nmp->nm_sotype != SOCK_STREAM)
261 panic("nfscon sotype");
262 if (so->so_proto->pr_flags & PR_CONNREQUIRED) {
263 MGET(m, M_WAIT, MT_SOOPTS);
264 *mtod(m, int32_t *) = 1;
265 m->m_len = sizeof(int32_t);
266 sosetopt(so, SOL_SOCKET, SO_KEEPALIVE, m);
267 }
268 if (so->so_proto->pr_protocol == IPPROTO_TCP) {
269 MGET(m, M_WAIT, MT_SOOPTS);
270 *mtod(m, int32_t *) = 1;
271 m->m_len = sizeof(int32_t);
272 sosetopt(so, IPPROTO_TCP, TCP_NODELAY, m);
273 }
274 sndreserve = (nmp->nm_wsize + NFS_MAXPKTHDR +
275 sizeof (u_int32_t)) * 2;
276 rcvreserve = (nmp->nm_rsize + NFS_MAXPKTHDR +
277 sizeof (u_int32_t)) * 2;
278 }
279 error = soreserve(so, sndreserve, rcvreserve);
280 if (error)
281 goto bad;
282 so->so_rcv.sb_flags |= SB_NOINTR;
283 so->so_snd.sb_flags |= SB_NOINTR;
284
285
286 nmp->nm_srtt[0] = nmp->nm_srtt[1] = nmp->nm_srtt[2] =
287 nmp->nm_srtt[3] = (NFS_TIMEO << 3);
288 nmp->nm_sdrtt[0] = nmp->nm_sdrtt[1] = nmp->nm_sdrtt[2] =
289 nmp->nm_sdrtt[3] = 0;
290 nmp->nm_cwnd = NFS_MAXCWND / 2;
291 nmp->nm_sent = 0;
292 nmp->nm_timeouts = 0;
293 return (0);
294
295 bad:
296 nfs_disconnect(nmp);
297 return (error);
298 }
299
300
301
302
303
304
305
306
307
308
309 int
310 nfs_reconnect(rep)
311 struct nfsreq *rep;
312 {
313 struct nfsreq *rp;
314 struct nfsmount *nmp = rep->r_nmp;
315 int error;
316
317 nfs_disconnect(nmp);
318 while ((error = nfs_connect(nmp, rep)) != 0) {
319 if (error == EINTR || error == ERESTART)
320 return (EINTR);
321 (void) tsleep((caddr_t)&lbolt, PSOCK, "nfscon", 0);
322 }
323
324
325
326
327
328 TAILQ_FOREACH(rp, &nfs_reqq, r_chain) {
329 if (rp->r_nmp == nmp) {
330 rp->r_flags |= R_MUSTRESEND;
331 rp->r_rexmit = 0;
332 }
333 }
334 return (0);
335 }
336
337
338
339
340 void
341 nfs_disconnect(nmp)
342 struct nfsmount *nmp;
343 {
344 struct socket *so;
345
346 if (nmp->nm_so) {
347 so = nmp->nm_so;
348 nmp->nm_so = (struct socket *)0;
349 soshutdown(so, SHUT_RDWR);
350 soclose(so);
351 }
352 }
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367 int
368 nfs_send(so, nam, top, rep)
369 struct socket *so;
370 struct mbuf *nam;
371 struct mbuf *top;
372 struct nfsreq *rep;
373 {
374 struct mbuf *sendnam;
375 int error, soflags, flags;
376
377 if (rep) {
378 if (rep->r_flags & R_SOFTTERM) {
379 m_freem(top);
380 return (EINTR);
381 }
382 if ((so = rep->r_nmp->nm_so) == NULL) {
383 rep->r_flags |= R_MUSTRESEND;
384 m_freem(top);
385 return (0);
386 }
387 rep->r_flags &= ~R_MUSTRESEND;
388 soflags = rep->r_nmp->nm_soflags;
389 } else
390 soflags = so->so_proto->pr_flags;
391 if ((soflags & PR_CONNREQUIRED) || (so->so_state & SS_ISCONNECTED))
392 sendnam = (struct mbuf *)0;
393 else
394 sendnam = nam;
395 if (so->so_type == SOCK_SEQPACKET)
396 flags = MSG_EOR;
397 else
398 flags = 0;
399
400 error = sosend(so, sendnam, (struct uio *)0, top,
401 (struct mbuf *)0, flags);
402 if (error) {
403 if (rep) {
404
405
406
407 if (rep->r_flags & R_SOFTTERM)
408 error = EINTR;
409 else
410 rep->r_flags |= R_MUSTRESEND;
411 }
412
413
414
415
416 if (error != EINTR && error != ERESTART &&
417 error != EWOULDBLOCK && error != EPIPE)
418 error = 0;
419 }
420 return (error);
421 }
422
423 #ifdef NFSCLIENT
424
425
426
427
428
429
430
431
432
433 int
434 nfs_receive(rep, aname, mp)
435 struct nfsreq *rep;
436 struct mbuf **aname;
437 struct mbuf **mp;
438 {
439 struct socket *so;
440 struct uio auio;
441 struct iovec aio;
442 struct mbuf *m;
443 struct mbuf *control;
444 u_int32_t len;
445 struct mbuf **getnam;
446 int error, sotype, rcvflg;
447 struct proc *p = curproc;
448
449
450
451
452 *mp = (struct mbuf *)0;
453 *aname = (struct mbuf *)0;
454 sotype = rep->r_nmp->nm_sotype;
455
456
457
458
459
460
461
462
463
464 if (sotype != SOCK_DGRAM) {
465 error = nfs_sndlock(&rep->r_nmp->nm_flag, rep);
466 if (error)
467 return (error);
468 tryagain:
469
470
471
472
473
474
475
476
477
478 if (rep->r_mrep || (rep->r_flags & R_SOFTTERM)) {
479 nfs_sndunlock(&rep->r_nmp->nm_flag);
480 return (EINTR);
481 }
482 so = rep->r_nmp->nm_so;
483 if (!so) {
484 error = nfs_reconnect(rep);
485 if (error) {
486 nfs_sndunlock(&rep->r_nmp->nm_flag);
487 return (error);
488 }
489 goto tryagain;
490 }
491 while (rep->r_flags & R_MUSTRESEND) {
492 m = m_copym(rep->r_mreq, 0, M_COPYALL, M_WAIT);
493 nfsstats.rpcretries++;
494 rep->r_rtt = 0;
495 rep->r_flags &= ~R_TIMING;
496 error = nfs_send(so, rep->r_nmp->nm_nam, m, rep);
497 if (error) {
498 if (error == EINTR || error == ERESTART ||
499 (error = nfs_reconnect(rep)) != 0) {
500 nfs_sndunlock(&rep->r_nmp->nm_flag);
501 return (error);
502 }
503 goto tryagain;
504 }
505 }
506 nfs_sndunlock(&rep->r_nmp->nm_flag);
507 if (sotype == SOCK_STREAM) {
508 aio.iov_base = (caddr_t) &len;
509 aio.iov_len = sizeof(u_int32_t);
510 auio.uio_iov = &aio;
511 auio.uio_iovcnt = 1;
512 auio.uio_segflg = UIO_SYSSPACE;
513 auio.uio_rw = UIO_READ;
514 auio.uio_offset = 0;
515 auio.uio_resid = sizeof(u_int32_t);
516 auio.uio_procp = p;
517 do {
518 rcvflg = MSG_WAITALL;
519 error = soreceive(so, (struct mbuf **)0, &auio,
520 (struct mbuf **)0, (struct mbuf **)0, &rcvflg);
521 if (error == EWOULDBLOCK && rep) {
522 if (rep->r_flags & R_SOFTTERM)
523 return (EINTR);
524
525
526
527
528
529
530 if (rep->r_rexmit >= rep->r_nmp->nm_retry) {
531 nfsstats.rpctimeouts++;
532 error = EPIPE;
533 }
534 }
535 } while (error == EWOULDBLOCK);
536 if (!error && auio.uio_resid > 0) {
537 log(LOG_INFO,
538 "short receive (%d/%d) from nfs server %s\n",
539 sizeof(u_int32_t) - auio.uio_resid,
540 sizeof(u_int32_t),
541 rep->r_nmp->nm_mountp->mnt_stat.f_mntfromname);
542 error = EPIPE;
543 }
544 if (error)
545 goto errout;
546
547 len = ntohl(len) & ~0x80000000;
548
549
550
551
552 if (len > NFS_MAXPACKET) {
553 log(LOG_ERR, "%s (%d) from nfs server %s\n",
554 "impossible packet length",
555 len,
556 rep->r_nmp->nm_mountp->mnt_stat.f_mntfromname);
557 error = EFBIG;
558 goto errout;
559 }
560 auio.uio_resid = len;
561 do {
562 rcvflg = MSG_WAITALL;
563 error = soreceive(so, (struct mbuf **)0,
564 &auio, mp, (struct mbuf **)0, &rcvflg);
565 } while (error == EWOULDBLOCK || error == EINTR ||
566 error == ERESTART);
567 if (!error && auio.uio_resid > 0) {
568 log(LOG_INFO,
569 "short receive (%d/%d) from nfs server %s\n",
570 len - auio.uio_resid, len,
571 rep->r_nmp->nm_mountp->mnt_stat.f_mntfromname);
572 error = EPIPE;
573 }
574 } else {
575
576
577
578
579
580
581
582
583 auio.uio_resid = len = 100000000;
584 auio.uio_procp = p;
585 do {
586 rcvflg = 0;
587 error = soreceive(so, (struct mbuf **)0,
588 &auio, mp, &control, &rcvflg);
589 if (control)
590 m_freem(control);
591 if (error == EWOULDBLOCK && rep) {
592 if (rep->r_flags & R_SOFTTERM)
593 return (EINTR);
594 }
595 } while (error == EWOULDBLOCK ||
596 (!error && *mp == NULL && control));
597 if ((rcvflg & MSG_EOR) == 0)
598 printf("Egad!!\n");
599 if (!error && *mp == NULL)
600 error = EPIPE;
601 len -= auio.uio_resid;
602 }
603 errout:
604 if (error && error != EINTR && error != ERESTART) {
605 m_freem(*mp);
606 *mp = (struct mbuf *)0;
607 if (error != EPIPE)
608 log(LOG_INFO,
609 "receive error %d from nfs server %s\n",
610 error,
611 rep->r_nmp->nm_mountp->mnt_stat.f_mntfromname);
612 error = nfs_sndlock(&rep->r_nmp->nm_flag, rep);
613 if (!error) {
614 error = nfs_reconnect(rep);
615 if (!error)
616 goto tryagain;
617 nfs_sndunlock(&rep->r_nmp->nm_flag);
618 }
619 }
620 } else {
621 if ((so = rep->r_nmp->nm_so) == NULL)
622 return (EACCES);
623 if (so->so_state & SS_ISCONNECTED)
624 getnam = (struct mbuf **)0;
625 else
626 getnam = aname;
627 auio.uio_resid = len = 1000000;
628 auio.uio_procp = p;
629 do {
630 rcvflg = 0;
631 error = soreceive(so, getnam, &auio, mp,
632 (struct mbuf **)0, &rcvflg);
633 if (error == EWOULDBLOCK &&
634 (rep->r_flags & R_SOFTTERM))
635 return (EINTR);
636 } while (error == EWOULDBLOCK);
637 len -= auio.uio_resid;
638 }
639 if (error) {
640 m_freem(*mp);
641 *mp = (struct mbuf *)0;
642 }
643
644
645
646
647
648
649 nfs_realign(mp, 5 * NFSX_UNSIGNED);
650 return (error);
651 }
652
653
654
655
656
657
658
659 int
660 nfs_reply(myrep)
661 struct nfsreq *myrep;
662 {
663 struct nfsreq *rep;
664 struct nfsmount *nmp = myrep->r_nmp;
665 int32_t t1;
666 struct mbuf *mrep, *nam, *md;
667 u_int32_t rxid, *tl;
668 caddr_t dpos, cp2;
669 int error;
670
671
672
673
674 for (;;) {
675
676
677
678
679
680
681 error = nfs_rcvlock(myrep);
682 if (error)
683 return (error);
684
685 if (myrep->r_mrep != NULL) {
686 nfs_rcvunlock(&nmp->nm_flag);
687 return (0);
688 }
689
690
691
692 error = nfs_receive(myrep, &nam, &mrep);
693 nfs_rcvunlock(&nmp->nm_flag);
694 if (error) {
695
696
697
698
699 if (NFSIGNORE_SOERROR(nmp->nm_soflags, error)) {
700 if (nmp->nm_so)
701 nmp->nm_so->so_error = 0;
702 if (myrep->r_flags & R_GETONEREP)
703 return (0);
704 continue;
705 }
706 return (error);
707 }
708 if (nam)
709 m_freem(nam);
710
711
712
713
714 md = mrep;
715 dpos = mtod(md, caddr_t);
716 nfsm_dissect(tl, u_int32_t *, 2*NFSX_UNSIGNED);
717 rxid = *tl++;
718 if (*tl != rpc_reply) {
719 nfsstats.rpcinvalid++;
720 m_freem(mrep);
721 nfsmout:
722 if (myrep->r_flags & R_GETONEREP)
723 return (0);
724 continue;
725 }
726
727
728
729
730
731 for (rep = TAILQ_FIRST(&nfs_reqq); rep != NULL;
732 rep = TAILQ_NEXT(rep, r_chain)) {
733 if (rep->r_mrep == NULL && rxid == rep->r_xid) {
734
735 rep->r_mrep = mrep;
736 rep->r_md = md;
737 rep->r_dpos = dpos;
738 if (nfsrtton) {
739 struct rttl *rt;
740
741 rt = &nfsrtt.rttl[nfsrtt.pos];
742 rt->proc = rep->r_procnum;
743 rt->rto = NFS_RTO(nmp, proct[rep->r_procnum]);
744 rt->sent = nmp->nm_sent;
745 rt->cwnd = nmp->nm_cwnd;
746 rt->srtt = nmp->nm_srtt[proct[rep->r_procnum] - 1];
747 rt->sdrtt = nmp->nm_sdrtt[proct[rep->r_procnum] - 1];
748 rt->fsid = nmp->nm_mountp->mnt_stat.f_fsid;
749 getmicrotime(&rt->tstamp);
750 if (rep->r_flags & R_TIMING)
751 rt->rtt = rep->r_rtt;
752 else
753 rt->rtt = 1000000;
754 nfsrtt.pos = (nfsrtt.pos + 1) % NFSRTTLOGSIZ;
755 }
756
757
758
759
760
761 if (nmp->nm_cwnd <= nmp->nm_sent) {
762 nmp->nm_cwnd +=
763 (NFS_CWNDSCALE * NFS_CWNDSCALE +
764 (nmp->nm_cwnd >> 1)) / nmp->nm_cwnd;
765 if (nmp->nm_cwnd > NFS_MAXCWND)
766 nmp->nm_cwnd = NFS_MAXCWND;
767 }
768 rep->r_flags &= ~R_SENT;
769 nmp->nm_sent -= NFS_CWNDSCALE;
770
771
772
773
774 if (rep->r_flags & R_TIMING) {
775
776
777
778
779
780
781
782
783 t1 = rep->r_rtt + 1;
784 t1 -= (NFS_SRTT(rep) >> 3);
785 NFS_SRTT(rep) += t1;
786 if (t1 < 0)
787 t1 = -t1;
788 t1 -= (NFS_SDRTT(rep) >> 2);
789 NFS_SDRTT(rep) += t1;
790 }
791 nmp->nm_timeouts = 0;
792 break;
793 }
794 }
795
796
797
798
799 if (rep == 0) {
800 nfsstats.rpcunexpected++;
801 m_freem(mrep);
802 } else if (rep == myrep) {
803 if (rep->r_mrep == NULL)
804 panic("nfsreply nil");
805 return (0);
806 }
807 if (myrep->r_flags & R_GETONEREP)
808 return (0);
809 }
810 }
811
812
813
814
815
816
817
818
819
820
821
822 int
823 nfs_request(vp, mrest, procnum, procp, cred, mrp, mdp, dposp)
824 struct vnode *vp;
825 struct mbuf *mrest;
826 int procnum;
827 struct proc *procp;
828 struct ucred *cred;
829 struct mbuf **mrp;
830 struct mbuf **mdp;
831 caddr_t *dposp;
832 {
833 struct mbuf *m, *mrep;
834 struct nfsreq *rep;
835 u_int32_t *tl;
836 int i;
837 struct nfsmount *nmp;
838 struct mbuf *md, *mheadend;
839 char nickv[RPCX_NICKVERF];
840 time_t reqtime, waituntil;
841 caddr_t dpos, cp2;
842 int t1, s, error = 0, mrest_len, auth_len, auth_type;
843 int trylater_delay, failed_auth = 0;
844 int verf_len, verf_type;
845 u_int32_t xid;
846 char *auth_str, *verf_str;
847 NFSKERBKEY_T key;
848
849 trylater_delay = NFS_MINTIMEO;
850
851 nmp = VFSTONFS(vp->v_mount);
852 rep = pool_get(&nfsreqpl, PR_WAITOK);
853 rep->r_nmp = nmp;
854 rep->r_vp = vp;
855 rep->r_procp = procp;
856 rep->r_procnum = procnum;
857 i = 0;
858 m = mrest;
859 while (m) {
860 i += m->m_len;
861 m = m->m_next;
862 }
863 mrest_len = i;
864
865
866
867
868 kerbauth:
869 verf_str = auth_str = (char *)0;
870 if (nmp->nm_flag & NFSMNT_KERB) {
871 verf_str = nickv;
872 verf_len = sizeof (nickv);
873 auth_type = RPCAUTH_KERB4;
874 bzero((caddr_t)key, sizeof (key));
875 if (failed_auth || nfs_getnickauth(nmp, cred, &auth_str,
876 &auth_len, verf_str, verf_len)) {
877 error = nfs_getauth(nmp, rep, cred, &auth_str,
878 &auth_len, verf_str, &verf_len, key);
879 if (error) {
880 pool_put(&nfsreqpl, rep);
881 m_freem(mrest);
882 return (error);
883 }
884 }
885 } else {
886 auth_type = RPCAUTH_UNIX;
887 auth_len = (((cred->cr_ngroups > nmp->nm_numgrps) ?
888 nmp->nm_numgrps : cred->cr_ngroups) << 2) +
889 5 * NFSX_UNSIGNED;
890 }
891 m = nfsm_rpchead(cred, nmp->nm_flag, procnum, auth_type, auth_len,
892 auth_str, verf_len, verf_str, mrest, mrest_len, &mheadend, &xid);
893 if (auth_str)
894 free(auth_str, M_TEMP);
895
896
897
898
899 if (nmp->nm_sotype == SOCK_STREAM) {
900 M_PREPEND(m, NFSX_UNSIGNED, M_WAIT);
901 *mtod(m, u_int32_t *) = htonl(0x80000000 |
902 (m->m_pkthdr.len - NFSX_UNSIGNED));
903 }
904 rep->r_mreq = m;
905 rep->r_xid = xid;
906 tryagain:
907 if (nmp->nm_flag & NFSMNT_SOFT)
908 rep->r_retry = nmp->nm_retry;
909 else
910 rep->r_retry = NFS_MAXREXMIT + 1;
911 rep->r_rtt = rep->r_rexmit = 0;
912 if (proct[procnum] > 0)
913 rep->r_flags = R_TIMING;
914 else
915 rep->r_flags = 0;
916 rep->r_mrep = NULL;
917
918
919
920
921 nfsstats.rpcrequests++;
922
923
924
925
926 s = splsoftnet();
927 TAILQ_INSERT_TAIL(&nfs_reqq, rep, r_chain);
928
929
930 reqtime = time_second;
931
932
933
934
935
936
937 if (nmp->nm_so && (nmp->nm_sotype != SOCK_DGRAM ||
938 (nmp->nm_flag & NFSMNT_DUMBTIMR) ||
939 nmp->nm_sent < nmp->nm_cwnd)) {
940 splx(s);
941 if (nmp->nm_soflags & PR_CONNREQUIRED)
942 error = nfs_sndlock(&nmp->nm_flag, rep);
943 if (!error) {
944 error = nfs_send(nmp->nm_so, nmp->nm_nam,
945 m_copym(m, 0, M_COPYALL, M_WAIT),
946 rep);
947 if (nmp->nm_soflags & PR_CONNREQUIRED)
948 nfs_sndunlock(&nmp->nm_flag);
949 }
950 if (!error && (rep->r_flags & R_MUSTRESEND) == 0) {
951 nmp->nm_sent += NFS_CWNDSCALE;
952 rep->r_flags |= R_SENT;
953 }
954 } else {
955 splx(s);
956 rep->r_rtt = -1;
957 }
958
959
960
961
962 if (!error || error == EPIPE)
963 error = nfs_reply(rep);
964
965
966
967
968 s = splsoftnet();
969 TAILQ_REMOVE(&nfs_reqq, rep, r_chain);
970 splx(s);
971
972
973
974
975 if (rep->r_flags & R_SENT) {
976 rep->r_flags &= ~R_SENT;
977 nmp->nm_sent -= NFS_CWNDSCALE;
978 }
979
980
981
982
983
984 if (!error && (rep->r_flags & R_TPRINTFMSG))
985 nfs_msg(rep->r_procp, nmp->nm_mountp->mnt_stat.f_mntfromname,
986 "is alive again");
987 mrep = rep->r_mrep;
988 md = rep->r_md;
989 dpos = rep->r_dpos;
990 if (error) {
991 m_freem(rep->r_mreq);
992 pool_put(&nfsreqpl, rep);
993 return (error);
994 }
995
996
997
998
999 nfsm_dissect(tl, u_int32_t *, 3 * NFSX_UNSIGNED);
1000 if (*tl++ == rpc_msgdenied) {
1001 if (*tl == rpc_mismatch)
1002 error = EOPNOTSUPP;
1003 else if ((nmp->nm_flag & NFSMNT_KERB) && *tl++ == rpc_autherr) {
1004 if (!failed_auth) {
1005 failed_auth++;
1006 mheadend->m_next = (struct mbuf *)0;
1007 m_freem(mrep);
1008 m_freem(rep->r_mreq);
1009 goto kerbauth;
1010 } else
1011 error = EAUTH;
1012 } else
1013 error = EACCES;
1014 m_freem(mrep);
1015 m_freem(rep->r_mreq);
1016 pool_put(&nfsreqpl, rep);
1017 return (error);
1018 }
1019
1020
1021
1022
1023 verf_type = fxdr_unsigned(int, *tl++);
1024 i = fxdr_unsigned(int32_t, *tl);
1025 if ((nmp->nm_flag & NFSMNT_KERB) && verf_type == RPCAUTH_KERB4) {
1026 error = nfs_savenickauth(nmp, cred, i, key, &md, &dpos, mrep);
1027 if (error)
1028 goto nfsmout;
1029 } else if (i > 0)
1030 nfsm_adv(nfsm_rndup(i));
1031 nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED);
1032
1033 if (*tl == 0) {
1034 nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED);
1035 if (*tl != 0) {
1036 error = fxdr_unsigned(int, *tl);
1037 if ((nmp->nm_flag & NFSMNT_NFSV3) &&
1038 error == NFSERR_TRYLATER) {
1039 m_freem(mrep);
1040 error = 0;
1041 waituntil = time_second + trylater_delay;
1042 while (time_second < waituntil)
1043 (void) tsleep((caddr_t)&lbolt,
1044 PSOCK, "nqnfstry", 0);
1045 trylater_delay *= NFS_TIMEOUTMUL;
1046 if (trylater_delay > NFS_MAXTIMEO)
1047 trylater_delay = NFS_MAXTIMEO;
1048
1049 goto tryagain;
1050 }
1051
1052
1053
1054
1055
1056 if (error == ESTALE)
1057 cache_purge(vp);
1058
1059 if (nmp->nm_flag & NFSMNT_NFSV3 || error == ESTALE) {
1060 *mrp = mrep;
1061 *mdp = md;
1062 *dposp = dpos;
1063 error |= NFSERR_RETERR;
1064 } else
1065 m_freem(mrep);
1066 m_freem(rep->r_mreq);
1067 pool_put(&nfsreqpl, rep);
1068 return (error);
1069 }
1070
1071 *mrp = mrep;
1072 *mdp = md;
1073 *dposp = dpos;
1074 m_freem(rep->r_mreq);
1075 pool_put(&nfsreqpl, rep);
1076 return (0);
1077 }
1078 m_freem(mrep);
1079 error = EPROTONOSUPPORT;
1080 nfsmout:
1081 m_freem(rep->r_mreq);
1082 pool_put(&nfsreqpl, rep);
1083 return (error);
1084 }
1085 #endif
1086
1087
1088
1089
1090
1091 int
1092 nfs_rephead(siz, nd, slp, err, frev, mrq, mbp, bposp)
1093 int siz;
1094 struct nfsrv_descript *nd;
1095 struct nfssvc_sock *slp;
1096 int err;
1097 u_quad_t *frev;
1098 struct mbuf **mrq;
1099 struct mbuf **mbp;
1100 caddr_t *bposp;
1101 {
1102 u_int32_t *tl;
1103 struct mbuf *mreq;
1104 caddr_t bpos;
1105 struct mbuf *mb, *mb2;
1106
1107 MGETHDR(mreq, M_WAIT, MT_DATA);
1108 mb = mreq;
1109
1110
1111
1112
1113 siz += RPC_REPLYSIZ;
1114 if (siz >= max_datalen) {
1115 MCLGET(mreq, M_WAIT);
1116 } else
1117 mreq->m_data += max_hdr;
1118 tl = mtod(mreq, u_int32_t *);
1119 mreq->m_len = 6 * NFSX_UNSIGNED;
1120 bpos = ((caddr_t)tl) + mreq->m_len;
1121 *tl++ = txdr_unsigned(nd->nd_retxid);
1122 *tl++ = rpc_reply;
1123 if (err == ERPCMISMATCH || (err & NFSERR_AUTHERR)) {
1124 *tl++ = rpc_msgdenied;
1125 if (err & NFSERR_AUTHERR) {
1126 *tl++ = rpc_autherr;
1127 *tl = txdr_unsigned(err & ~NFSERR_AUTHERR);
1128 mreq->m_len -= NFSX_UNSIGNED;
1129 bpos -= NFSX_UNSIGNED;
1130 } else {
1131 *tl++ = rpc_mismatch;
1132 *tl++ = txdr_unsigned(RPC_VER2);
1133 *tl = txdr_unsigned(RPC_VER2);
1134 }
1135 } else {
1136 *tl++ = rpc_msgaccepted;
1137
1138
1139
1140
1141
1142 if (nd->nd_flag & ND_KERBFULL) {
1143 struct nfsuid *nuidp;
1144 struct timeval ktvin, ktvout;
1145
1146 LIST_FOREACH(nuidp, NUIDHASH(slp, nd->nd_cr.cr_uid),
1147 nu_hash) {
1148 if (nuidp->nu_cr.cr_uid == nd->nd_cr.cr_uid &&
1149 (!nd->nd_nam2 || netaddr_match(NU_NETFAM(nuidp),
1150 &nuidp->nu_haddr, nd->nd_nam2)))
1151 break;
1152 }
1153 if (nuidp) {
1154 ktvin.tv_sec =
1155 txdr_unsigned(nuidp->nu_timestamp.tv_sec - 1);
1156 ktvin.tv_usec =
1157 txdr_unsigned(nuidp->nu_timestamp.tv_usec);
1158
1159 *tl++ = rpc_auth_kerb;
1160 *tl++ = txdr_unsigned(3 * NFSX_UNSIGNED);
1161 *tl = ktvout.tv_sec;
1162 nfsm_build(tl, u_int32_t *, 3 * NFSX_UNSIGNED);
1163 *tl++ = ktvout.tv_usec;
1164 *tl++ = txdr_unsigned(nuidp->nu_cr.cr_uid);
1165 } else {
1166 *tl++ = 0;
1167 *tl++ = 0;
1168 }
1169 } else {
1170 *tl++ = 0;
1171 *tl++ = 0;
1172 }
1173 switch (err) {
1174 case EPROGUNAVAIL:
1175 *tl = txdr_unsigned(RPC_PROGUNAVAIL);
1176 break;
1177 case EPROGMISMATCH:
1178 *tl = txdr_unsigned(RPC_PROGMISMATCH);
1179 nfsm_build(tl, u_int32_t *, 2 * NFSX_UNSIGNED);
1180 *tl++ = txdr_unsigned(2);
1181 *tl = txdr_unsigned(3);
1182 break;
1183 case EPROCUNAVAIL:
1184 *tl = txdr_unsigned(RPC_PROCUNAVAIL);
1185 break;
1186 case EBADRPC:
1187 *tl = txdr_unsigned(RPC_GARBAGE);
1188 break;
1189 default:
1190 *tl = 0;
1191 if (err != NFSERR_RETVOID) {
1192 nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED);
1193 if (err)
1194 *tl = txdr_unsigned(nfsrv_errmap(nd, err));
1195 else
1196 *tl = 0;
1197 }
1198 break;
1199 };
1200 }
1201
1202 *mrq = mreq;
1203 if (mbp != NULL)
1204 *mbp = mb;
1205 *bposp = bpos;
1206 if (err != 0 && err != NFSERR_RETVOID)
1207 nfsstats.srvrpc_errs++;
1208 return (0);
1209 }
1210
1211
1212
1213
1214
1215
1216
1217 void
1218 nfs_timer(arg)
1219 void *arg;
1220 {
1221 struct timeout *to = (struct timeout *)arg;
1222 struct nfsreq *rep;
1223 struct mbuf *m;
1224 struct socket *so;
1225 struct nfsmount *nmp;
1226 int timeo;
1227 int s, error;
1228 #ifdef NFSSERVER
1229 struct nfssvc_sock *slp;
1230 struct timeval tv;
1231 u_quad_t cur_usec;
1232 #endif
1233
1234 s = splsoftnet();
1235 for (rep = TAILQ_FIRST(&nfs_reqq); rep != NULL;
1236 rep = TAILQ_NEXT(rep, r_chain)) {
1237 nmp = rep->r_nmp;
1238 if (rep->r_mrep || (rep->r_flags & R_SOFTTERM))
1239 continue;
1240 if (nfs_sigintr(nmp, rep, rep->r_procp)) {
1241 rep->r_flags |= R_SOFTTERM;
1242 continue;
1243 }
1244 if (rep->r_rtt >= 0) {
1245 rep->r_rtt++;
1246 if (nmp->nm_flag & NFSMNT_DUMBTIMR)
1247 timeo = nmp->nm_timeo;
1248 else
1249 timeo = NFS_RTO(nmp, proct[rep->r_procnum]);
1250 if (nmp->nm_timeouts > 0)
1251 timeo *= nfs_backoff[nmp->nm_timeouts - 1];
1252 if (rep->r_rtt <= timeo)
1253 continue;
1254 if (nmp->nm_timeouts < 8)
1255 nmp->nm_timeouts++;
1256 }
1257
1258
1259
1260 if ((rep->r_flags & R_TPRINTFMSG) == 0 &&
1261 rep->r_rexmit > nmp->nm_deadthresh) {
1262 nfs_msg(rep->r_procp,
1263 nmp->nm_mountp->mnt_stat.f_mntfromname,
1264 "not responding");
1265 rep->r_flags |= R_TPRINTFMSG;
1266 }
1267 if (rep->r_rexmit >= rep->r_retry) {
1268 nfsstats.rpctimeouts++;
1269 rep->r_flags |= R_SOFTTERM;
1270 continue;
1271 }
1272 if (nmp->nm_sotype != SOCK_DGRAM) {
1273 if (++rep->r_rexmit > NFS_MAXREXMIT)
1274 rep->r_rexmit = NFS_MAXREXMIT;
1275 continue;
1276 }
1277 if ((so = nmp->nm_so) == NULL)
1278 continue;
1279
1280
1281
1282
1283
1284
1285 rep->r_rtt = -1;
1286 if (sbspace(&so->so_snd) >= rep->r_mreq->m_pkthdr.len &&
1287 ((nmp->nm_flag & NFSMNT_DUMBTIMR) ||
1288 (rep->r_flags & R_SENT) ||
1289 nmp->nm_sent < nmp->nm_cwnd) &&
1290 (m = m_copym(rep->r_mreq, 0, M_COPYALL, M_DONTWAIT))){
1291 if ((nmp->nm_flag & NFSMNT_NOCONN) == 0)
1292 error = (*so->so_proto->pr_usrreq)(so, PRU_SEND, m,
1293 (struct mbuf *)0, (struct mbuf *)0);
1294 else
1295 error = (*so->so_proto->pr_usrreq)(so, PRU_SEND, m,
1296 nmp->nm_nam, (struct mbuf *)0);
1297 if (error) {
1298 if (NFSIGNORE_SOERROR(nmp->nm_soflags, error))
1299 so->so_error = 0;
1300 } else {
1301
1302
1303
1304
1305
1306 if (rep->r_flags & R_SENT) {
1307 rep->r_flags &= ~R_TIMING;
1308 if (++rep->r_rexmit > NFS_MAXREXMIT)
1309 rep->r_rexmit = NFS_MAXREXMIT;
1310 nmp->nm_cwnd >>= 1;
1311 if (nmp->nm_cwnd < NFS_CWNDSCALE)
1312 nmp->nm_cwnd = NFS_CWNDSCALE;
1313 nfsstats.rpcretries++;
1314 } else {
1315 rep->r_flags |= R_SENT;
1316 nmp->nm_sent += NFS_CWNDSCALE;
1317 }
1318 rep->r_rtt = 0;
1319 }
1320 }
1321 }
1322
1323 #ifdef NFSSERVER
1324
1325
1326
1327
1328 getmicrotime(&tv);
1329 cur_usec = (u_quad_t)tv.tv_sec * 1000000 + (u_quad_t)tv.tv_usec;
1330 for (slp = TAILQ_FIRST(&nfssvc_sockhead); slp != NULL;
1331 slp = TAILQ_NEXT(slp, ns_chain)) {
1332 if (LIST_FIRST(&slp->ns_tq) &&
1333 LIST_FIRST(&slp->ns_tq)->nd_time <= cur_usec)
1334 nfsrv_wakenfsd(slp);
1335 }
1336 #endif
1337 splx(s);
1338 timeout_add(to, nfs_ticks);
1339 }
1340
1341
1342
1343
1344
1345 int
1346 nfs_sigintr(nmp, rep, p)
1347 struct nfsmount *nmp;
1348 struct nfsreq *rep;
1349 struct proc *p;
1350 {
1351
1352 if (rep && (rep->r_flags & R_SOFTTERM))
1353 return (EINTR);
1354 if (!(nmp->nm_flag & NFSMNT_INT))
1355 return (0);
1356 if (p && p->p_siglist &&
1357 (((p->p_siglist & ~p->p_sigmask) & ~p->p_sigignore) &
1358 NFSINT_SIGMASK))
1359 return (EINTR);
1360 return (0);
1361 }
1362
1363
1364
1365
1366
1367
1368
1369 int
1370 nfs_sndlock(flagp, rep)
1371 int *flagp;
1372 struct nfsreq *rep;
1373 {
1374 struct proc *p;
1375 int slpflag = 0, slptimeo = 0;
1376
1377 if (rep) {
1378 p = rep->r_procp;
1379 if (rep->r_nmp->nm_flag & NFSMNT_INT)
1380 slpflag = PCATCH;
1381 } else
1382 p = (struct proc *)0;
1383 while (*flagp & NFSMNT_SNDLOCK) {
1384 if (nfs_sigintr(rep->r_nmp, rep, p))
1385 return (EINTR);
1386 *flagp |= NFSMNT_WANTSND;
1387 (void) tsleep((caddr_t)flagp, slpflag | (PZERO - 1), "nfsndlck",
1388 slptimeo);
1389 if (slpflag == PCATCH) {
1390 slpflag = 0;
1391 slptimeo = 2 * hz;
1392 }
1393 }
1394 *flagp |= NFSMNT_SNDLOCK;
1395 return (0);
1396 }
1397
1398
1399
1400
1401 void
1402 nfs_sndunlock(flagp)
1403 int *flagp;
1404 {
1405
1406 if ((*flagp & NFSMNT_SNDLOCK) == 0)
1407 panic("nfs sndunlock");
1408 *flagp &= ~NFSMNT_SNDLOCK;
1409 if (*flagp & NFSMNT_WANTSND) {
1410 *flagp &= ~NFSMNT_WANTSND;
1411 wakeup((caddr_t)flagp);
1412 }
1413 }
1414
1415 int
1416 nfs_rcvlock(rep)
1417 struct nfsreq *rep;
1418 {
1419 int *flagp = &rep->r_nmp->nm_flag;
1420 int slpflag, slptimeo = 0;
1421
1422 if (*flagp & NFSMNT_INT)
1423 slpflag = PCATCH;
1424 else
1425 slpflag = 0;
1426 while (*flagp & NFSMNT_RCVLOCK) {
1427 if (nfs_sigintr(rep->r_nmp, rep, rep->r_procp))
1428 return (EINTR);
1429 *flagp |= NFSMNT_WANTRCV;
1430 (void) tsleep((caddr_t)flagp, slpflag | (PZERO - 1), "nfsrcvlk",
1431 slptimeo);
1432 if (slpflag == PCATCH) {
1433 slpflag = 0;
1434 slptimeo = 2 * hz;
1435 }
1436 }
1437 *flagp |= NFSMNT_RCVLOCK;
1438 return (0);
1439 }
1440
1441
1442
1443
1444 void
1445 nfs_rcvunlock(flagp)
1446 int *flagp;
1447 {
1448
1449 if ((*flagp & NFSMNT_RCVLOCK) == 0)
1450 panic("nfs rcvunlock");
1451 *flagp &= ~NFSMNT_RCVLOCK;
1452 if (*flagp & NFSMNT_WANTRCV) {
1453 *flagp &= ~NFSMNT_WANTRCV;
1454 wakeup((caddr_t)flagp);
1455 }
1456 }
1457
1458
1459
1460
1461 void
1462 nfs_realign_fixup(struct mbuf *m, struct mbuf *n, unsigned int *off)
1463 {
1464 size_t padding;
1465
1466
1467
1468
1469
1470 while (n->m_next != NULL)
1471 n = n->m_next;
1472
1473
1474
1475
1476
1477 do {
1478 m = m->m_next;
1479 if (m == NULL)
1480 return;
1481
1482 padding = min(ALIGN(n->m_len) - n->m_len, m->m_len);
1483 if (padding > M_TRAILINGSPACE(n))
1484 panic("nfs_realign_fixup: no memory to pad to");
1485
1486 bcopy(mtod(m, void *), mtod(n, char *) + n->m_len, padding);
1487
1488 n->m_len += padding;
1489 m_adj(m, padding);
1490 *off += padding;
1491
1492 } while (!ALIGNED_POINTER(n->m_len, void *));
1493 }
1494
1495
1496
1497
1498
1499
1500 void
1501 nfs_realign(struct mbuf **pm, int hsiz)
1502 {
1503 struct mbuf *m;
1504 struct mbuf *n = NULL;
1505 unsigned int off = 0;
1506
1507 ++nfs_realign_test;
1508 while ((m = *pm) != NULL) {
1509 if (!ALIGNED_POINTER(m->m_data, void *) ||
1510 !ALIGNED_POINTER(m->m_len, void *)) {
1511 MGET(n, M_WAIT, MT_DATA);
1512 if (ALIGN(m->m_len) >= MINCLSIZE) {
1513 MCLGET(n, M_WAIT);
1514 }
1515 n->m_len = 0;
1516 break;
1517 }
1518 pm = &m->m_next;
1519 }
1520
1521
1522
1523
1524 if (n != NULL) {
1525 ++nfs_realign_count;
1526 while (m) {
1527 m_copyback(n, off, m->m_len, mtod(m, caddr_t));
1528
1529
1530
1531
1532
1533 if (!ALIGNED_POINTER(m->m_len, void *))
1534 nfs_realign_fixup(m, n, &off);
1535
1536 off += m->m_len;
1537 m = m->m_next;
1538 }
1539 m_freem(*pm);
1540 *pm = n;
1541 }
1542 }
1543
1544
1545
1546
1547
1548
1549
1550 int
1551 nfs_getreq(nd, nfsd, has_header)
1552 struct nfsrv_descript *nd;
1553 struct nfsd *nfsd;
1554 int has_header;
1555 {
1556 int len, i;
1557 u_int32_t *tl;
1558 int32_t t1;
1559 struct uio uio;
1560 struct iovec iov;
1561 caddr_t dpos, cp2, cp;
1562 u_int32_t nfsvers, auth_type;
1563 uid_t nickuid;
1564 int error = 0, ticklen;
1565 struct mbuf *mrep, *md;
1566 struct nfsuid *nuidp;
1567 struct timeval tvin, tvout;
1568
1569 mrep = nd->nd_mrep;
1570 md = nd->nd_md;
1571 dpos = nd->nd_dpos;
1572 if (has_header) {
1573 nfsm_dissect(tl, u_int32_t *, 10 * NFSX_UNSIGNED);
1574 nd->nd_retxid = fxdr_unsigned(u_int32_t, *tl++);
1575 if (*tl++ != rpc_call) {
1576 m_freem(mrep);
1577 return (EBADRPC);
1578 }
1579 } else
1580 nfsm_dissect(tl, u_int32_t *, 8 * NFSX_UNSIGNED);
1581 nd->nd_repstat = 0;
1582 nd->nd_flag = 0;
1583 if (*tl++ != rpc_vers) {
1584 nd->nd_repstat = ERPCMISMATCH;
1585 nd->nd_procnum = NFSPROC_NOOP;
1586 return (0);
1587 }
1588 if (*tl != nfs_prog) {
1589 nd->nd_repstat = EPROGUNAVAIL;
1590 nd->nd_procnum = NFSPROC_NOOP;
1591 return (0);
1592 }
1593 tl++;
1594 nfsvers = fxdr_unsigned(u_int32_t, *tl++);
1595 if (nfsvers != NFS_VER2 && nfsvers != NFS_VER3) {
1596 nd->nd_repstat = EPROGMISMATCH;
1597 nd->nd_procnum = NFSPROC_NOOP;
1598 return (0);
1599 }
1600 if (nfsvers == NFS_VER3)
1601 nd->nd_flag = ND_NFSV3;
1602 nd->nd_procnum = fxdr_unsigned(u_int32_t, *tl++);
1603 if (nd->nd_procnum == NFSPROC_NULL)
1604 return (0);
1605 if (nd->nd_procnum >= NFS_NPROCS ||
1606 (nd->nd_procnum > NFSPROC_COMMIT) ||
1607 (!nd->nd_flag && nd->nd_procnum > NFSV2PROC_STATFS)) {
1608 nd->nd_repstat = EPROCUNAVAIL;
1609 nd->nd_procnum = NFSPROC_NOOP;
1610 return (0);
1611 }
1612 if ((nd->nd_flag & ND_NFSV3) == 0)
1613 nd->nd_procnum = nfsv3_procid[nd->nd_procnum];
1614 auth_type = *tl++;
1615 len = fxdr_unsigned(int, *tl++);
1616 if (len < 0 || len > RPCAUTH_MAXSIZ) {
1617 m_freem(mrep);
1618 return (EBADRPC);
1619 }
1620
1621 nd->nd_flag &= ~ND_KERBAUTH;
1622
1623
1624
1625 if (auth_type == rpc_auth_unix) {
1626 len = fxdr_unsigned(int, *++tl);
1627 if (len < 0 || len > NFS_MAXNAMLEN) {
1628 m_freem(mrep);
1629 return (EBADRPC);
1630 }
1631 nfsm_adv(nfsm_rndup(len));
1632 nfsm_dissect(tl, u_int32_t *, 3 * NFSX_UNSIGNED);
1633 bzero((caddr_t)&nd->nd_cr, sizeof (struct ucred));
1634 nd->nd_cr.cr_ref = 1;
1635 nd->nd_cr.cr_uid = fxdr_unsigned(uid_t, *tl++);
1636 nd->nd_cr.cr_gid = fxdr_unsigned(gid_t, *tl++);
1637 len = fxdr_unsigned(int, *tl);
1638 if (len < 0 || len > RPCAUTH_UNIXGIDS) {
1639 m_freem(mrep);
1640 return (EBADRPC);
1641 }
1642 nfsm_dissect(tl, u_int32_t *, (len + 2) * NFSX_UNSIGNED);
1643 for (i = 0; i < len; i++)
1644 if (i < NGROUPS)
1645 nd->nd_cr.cr_groups[i] = fxdr_unsigned(gid_t, *tl++);
1646 else
1647 tl++;
1648 nd->nd_cr.cr_ngroups = (len > NGROUPS) ? NGROUPS : len;
1649 if (nd->nd_cr.cr_ngroups > 1)
1650 nfsrvw_sort(nd->nd_cr.cr_groups, nd->nd_cr.cr_ngroups);
1651 len = fxdr_unsigned(int, *++tl);
1652 if (len < 0 || len > RPCAUTH_MAXSIZ) {
1653 m_freem(mrep);
1654 return (EBADRPC);
1655 }
1656 if (len > 0)
1657 nfsm_adv(nfsm_rndup(len));
1658 } else if (auth_type == rpc_auth_kerb) {
1659 switch (fxdr_unsigned(int, *tl++)) {
1660 case RPCAKN_FULLNAME:
1661 ticklen = fxdr_unsigned(int, *tl);
1662 *((u_int32_t *)nfsd->nfsd_authstr) = *tl;
1663 uio.uio_resid = nfsm_rndup(ticklen) + NFSX_UNSIGNED;
1664 nfsd->nfsd_authlen = uio.uio_resid + NFSX_UNSIGNED;
1665 if (uio.uio_resid > (len - 2 * NFSX_UNSIGNED)) {
1666 m_freem(mrep);
1667 return (EBADRPC);
1668 }
1669 uio.uio_offset = 0;
1670 uio.uio_iov = &iov;
1671 uio.uio_iovcnt = 1;
1672 uio.uio_segflg = UIO_SYSSPACE;
1673 iov.iov_base = (caddr_t)&nfsd->nfsd_authstr[4];
1674 iov.iov_len = RPCAUTH_MAXSIZ - 4;
1675 nfsm_mtouio(&uio, uio.uio_resid);
1676 nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED);
1677 if (*tl++ != rpc_auth_kerb ||
1678 fxdr_unsigned(int, *tl) != 4 * NFSX_UNSIGNED) {
1679 printf("Bad kerb verifier\n");
1680 nd->nd_repstat = (NFSERR_AUTHERR|AUTH_BADVERF);
1681 nd->nd_procnum = NFSPROC_NOOP;
1682 return (0);
1683 }
1684 nfsm_dissect(cp, caddr_t, 4 * NFSX_UNSIGNED);
1685 tl = (u_int32_t *)cp;
1686 if (fxdr_unsigned(int, *tl) != RPCAKN_FULLNAME) {
1687 printf("Not fullname kerb verifier\n");
1688 nd->nd_repstat = (NFSERR_AUTHERR|AUTH_BADVERF);
1689 nd->nd_procnum = NFSPROC_NOOP;
1690 return (0);
1691 }
1692 cp += NFSX_UNSIGNED;
1693 bcopy(cp, nfsd->nfsd_verfstr, 3 * NFSX_UNSIGNED);
1694 nfsd->nfsd_verflen = 3 * NFSX_UNSIGNED;
1695 nd->nd_flag |= ND_KERBFULL;
1696 nfsd->nfsd_flag |= NFSD_NEEDAUTH;
1697 break;
1698 case RPCAKN_NICKNAME:
1699 if (len != 2 * NFSX_UNSIGNED) {
1700 printf("Kerb nickname short\n");
1701 nd->nd_repstat = (NFSERR_AUTHERR|AUTH_BADCRED);
1702 nd->nd_procnum = NFSPROC_NOOP;
1703 return (0);
1704 }
1705 nickuid = fxdr_unsigned(uid_t, *tl);
1706 nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED);
1707 if (*tl++ != rpc_auth_kerb ||
1708 fxdr_unsigned(int, *tl) != 3 * NFSX_UNSIGNED) {
1709 printf("Kerb nick verifier bad\n");
1710 nd->nd_repstat = (NFSERR_AUTHERR|AUTH_BADVERF);
1711 nd->nd_procnum = NFSPROC_NOOP;
1712 return (0);
1713 }
1714 nfsm_dissect(tl, u_int32_t *, 3 * NFSX_UNSIGNED);
1715 tvin.tv_sec = *tl++;
1716 tvin.tv_usec = *tl;
1717
1718 LIST_FOREACH(nuidp, NUIDHASH(nfsd->nfsd_slp, nickuid),
1719 nu_hash) {
1720 if (nuidp->nu_cr.cr_uid == nickuid &&
1721 (!nd->nd_nam2 ||
1722 netaddr_match(NU_NETFAM(nuidp),
1723 &nuidp->nu_haddr, nd->nd_nam2)))
1724 break;
1725 }
1726 if (!nuidp) {
1727 nd->nd_repstat =
1728 (NFSERR_AUTHERR|AUTH_REJECTCRED);
1729 nd->nd_procnum = NFSPROC_NOOP;
1730 return (0);
1731 }
1732
1733 tvout.tv_sec = fxdr_unsigned(long, tvout.tv_sec);
1734 tvout.tv_usec = fxdr_unsigned(long, tvout.tv_usec);
1735 if (nuidp->nu_expire < time_second ||
1736 nuidp->nu_timestamp.tv_sec > tvout.tv_sec ||
1737 (nuidp->nu_timestamp.tv_sec == tvout.tv_sec &&
1738 nuidp->nu_timestamp.tv_usec > tvout.tv_usec)) {
1739 nuidp->nu_expire = 0;
1740 nd->nd_repstat =
1741 (NFSERR_AUTHERR|AUTH_REJECTVERF);
1742 nd->nd_procnum = NFSPROC_NOOP;
1743 return (0);
1744 }
1745 nfsrv_setcred(&nuidp->nu_cr, &nd->nd_cr);
1746 nd->nd_flag |= ND_KERBNICK;
1747 };
1748 } else {
1749 nd->nd_repstat = (NFSERR_AUTHERR | AUTH_REJECTCRED);
1750 nd->nd_procnum = NFSPROC_NOOP;
1751 return (0);
1752 }
1753
1754 nd->nd_md = md;
1755 nd->nd_dpos = dpos;
1756 return (0);
1757 nfsmout:
1758 return (error);
1759 }
1760
1761 int
1762 nfs_msg(p, server, msg)
1763 struct proc *p;
1764 char *server, *msg;
1765 {
1766 tpr_t tpr;
1767
1768 if (p)
1769 tpr = tprintf_open(p);
1770 else
1771 tpr = NULL;
1772 tprintf(tpr, "nfs server %s: %s\n", server, msg);
1773 tprintf_close(tpr);
1774 return (0);
1775 }
1776
1777 #ifdef NFSSERVER
1778 int (*nfsrv3_procs[NFS_NPROCS])(struct nfsrv_descript *,
1779 struct nfssvc_sock *, struct proc *,
1780 struct mbuf **) = {
1781 nfsrv_null,
1782 nfsrv_getattr,
1783 nfsrv_setattr,
1784 nfsrv_lookup,
1785 nfsrv3_access,
1786 nfsrv_readlink,
1787 nfsrv_read,
1788 nfsrv_write,
1789 nfsrv_create,
1790 nfsrv_mkdir,
1791 nfsrv_symlink,
1792 nfsrv_mknod,
1793 nfsrv_remove,
1794 nfsrv_rmdir,
1795 nfsrv_rename,
1796 nfsrv_link,
1797 nfsrv_readdir,
1798 nfsrv_readdirplus,
1799 nfsrv_statfs,
1800 nfsrv_fsinfo,
1801 nfsrv_pathconf,
1802 nfsrv_commit,
1803 nfsrv_noop,
1804 nfsrv_noop,
1805 nfsrv_noop,
1806 nfsrv_noop
1807 };
1808
1809
1810
1811
1812
1813
1814
1815 void
1816 nfsrv_rcv(so, arg, waitflag)
1817 struct socket *so;
1818 caddr_t arg;
1819 int waitflag;
1820 {
1821 struct nfssvc_sock *slp = (struct nfssvc_sock *)arg;
1822 struct mbuf *m;
1823 struct mbuf *mp, *nam;
1824 struct uio auio;
1825 int flags, error;
1826
1827 if ((slp->ns_flag & SLP_VALID) == 0)
1828 return;
1829 #ifdef notdef
1830
1831
1832
1833 if (waitflag == M_DONTWAIT) {
1834 slp->ns_flag |= SLP_NEEDQ; goto dorecs;
1835 }
1836 #endif
1837 auio.uio_procp = NULL;
1838 if (so->so_type == SOCK_STREAM) {
1839
1840
1841
1842
1843
1844 if (slp->ns_rec && waitflag == M_DONTWAIT) {
1845 slp->ns_flag |= SLP_NEEDQ;
1846 goto dorecs;
1847 }
1848
1849
1850
1851
1852 auio.uio_resid = 1000000000;
1853 flags = MSG_DONTWAIT;
1854 error = soreceive(so, &nam, &auio, &mp, (struct mbuf **)0, &flags);
1855 if (error || mp == (struct mbuf *)0) {
1856 if (error == EWOULDBLOCK)
1857 slp->ns_flag |= SLP_NEEDQ;
1858 else
1859 slp->ns_flag |= SLP_DISCONN;
1860 goto dorecs;
1861 }
1862 m = mp;
1863 if (slp->ns_rawend) {
1864 slp->ns_rawend->m_next = m;
1865 slp->ns_cc += 1000000000 - auio.uio_resid;
1866 } else {
1867 slp->ns_raw = m;
1868 slp->ns_cc = 1000000000 - auio.uio_resid;
1869 }
1870 while (m->m_next)
1871 m = m->m_next;
1872 slp->ns_rawend = m;
1873
1874
1875
1876
1877 error = nfsrv_getstream(slp, waitflag);
1878 if (error) {
1879 if (error == EPERM)
1880 slp->ns_flag |= SLP_DISCONN;
1881 else
1882 slp->ns_flag |= SLP_NEEDQ;
1883 }
1884 } else {
1885 do {
1886 auio.uio_resid = 1000000000;
1887 flags = MSG_DONTWAIT;
1888 error = soreceive(so, &nam, &auio, &mp,
1889 (struct mbuf **)0, &flags);
1890 if (mp) {
1891 if (nam) {
1892 m = nam;
1893 m->m_next = mp;
1894 } else
1895 m = mp;
1896 if (slp->ns_recend)
1897 slp->ns_recend->m_nextpkt = m;
1898 else
1899 slp->ns_rec = m;
1900 slp->ns_recend = m;
1901 m->m_nextpkt = (struct mbuf *)0;
1902 }
1903 if (error) {
1904 if ((so->so_proto->pr_flags & PR_CONNREQUIRED)
1905 && error != EWOULDBLOCK) {
1906 slp->ns_flag |= SLP_DISCONN;
1907 goto dorecs;
1908 }
1909 }
1910 } while (mp);
1911 }
1912
1913
1914
1915
1916 dorecs:
1917 if (waitflag == M_DONTWAIT &&
1918 (slp->ns_rec || (slp->ns_flag & (SLP_NEEDQ | SLP_DISCONN))))
1919 nfsrv_wakenfsd(slp);
1920 }
1921
1922
1923
1924
1925
1926
1927 int
1928 nfsrv_getstream(slp, waitflag)
1929 struct nfssvc_sock *slp;
1930 int waitflag;
1931 {
1932 struct mbuf *m, **mpp;
1933 char *cp1, *cp2;
1934 int len;
1935 struct mbuf *om, *m2, *recm;
1936 u_int32_t recmark;
1937
1938 if (slp->ns_flag & SLP_GETSTREAM)
1939 panic("nfs getstream");
1940 slp->ns_flag |= SLP_GETSTREAM;
1941 for (;;) {
1942 if (slp->ns_reclen == 0) {
1943 if (slp->ns_cc < NFSX_UNSIGNED) {
1944 slp->ns_flag &= ~SLP_GETSTREAM;
1945 return (0);
1946 }
1947 m = slp->ns_raw;
1948 if (m->m_len >= NFSX_UNSIGNED) {
1949 bcopy(mtod(m, caddr_t), (caddr_t)&recmark, NFSX_UNSIGNED);
1950 m->m_data += NFSX_UNSIGNED;
1951 m->m_len -= NFSX_UNSIGNED;
1952 } else {
1953 cp1 = (caddr_t)&recmark;
1954 cp2 = mtod(m, caddr_t);
1955 while (cp1 < ((caddr_t)&recmark) + NFSX_UNSIGNED) {
1956 while (m->m_len == 0) {
1957 m = m->m_next;
1958 cp2 = mtod(m, caddr_t);
1959 }
1960 *cp1++ = *cp2++;
1961 m->m_data++;
1962 m->m_len--;
1963 }
1964 }
1965 slp->ns_cc -= NFSX_UNSIGNED;
1966 recmark = ntohl(recmark);
1967 slp->ns_reclen = recmark & ~0x80000000;
1968 if (recmark & 0x80000000)
1969 slp->ns_flag |= SLP_LASTFRAG;
1970 else
1971 slp->ns_flag &= ~SLP_LASTFRAG;
1972 if (slp->ns_reclen > NFS_MAXPACKET) {
1973 slp->ns_flag &= ~SLP_GETSTREAM;
1974 return (EPERM);
1975 }
1976 }
1977
1978
1979
1980
1981 recm = NULL;
1982 if (slp->ns_cc == slp->ns_reclen) {
1983 recm = slp->ns_raw;
1984 slp->ns_raw = slp->ns_rawend = (struct mbuf *)0;
1985 slp->ns_cc = slp->ns_reclen = 0;
1986 } else if (slp->ns_cc > slp->ns_reclen) {
1987 len = 0;
1988 m = slp->ns_raw;
1989 om = (struct mbuf *)0;
1990 while (len < slp->ns_reclen) {
1991 if ((len + m->m_len) > slp->ns_reclen) {
1992 m2 = m_copym(m, 0, slp->ns_reclen - len,
1993 waitflag);
1994 if (m2) {
1995 if (om) {
1996 om->m_next = m2;
1997 recm = slp->ns_raw;
1998 } else
1999 recm = m2;
2000 m->m_data += slp->ns_reclen - len;
2001 m->m_len -= slp->ns_reclen - len;
2002 len = slp->ns_reclen;
2003 } else {
2004 slp->ns_flag &= ~SLP_GETSTREAM;
2005 return (EWOULDBLOCK);
2006 }
2007 } else if ((len + m->m_len) == slp->ns_reclen) {
2008 om = m;
2009 len += m->m_len;
2010 m = m->m_next;
2011 recm = slp->ns_raw;
2012 om->m_next = (struct mbuf *)0;
2013 } else {
2014 om = m;
2015 len += m->m_len;
2016 m = m->m_next;
2017 }
2018 }
2019 slp->ns_raw = m;
2020 slp->ns_cc -= len;
2021 slp->ns_reclen = 0;
2022 } else {
2023 slp->ns_flag &= ~SLP_GETSTREAM;
2024 return (0);
2025 }
2026
2027
2028
2029
2030 mpp = &slp->ns_frag;
2031 while (*mpp)
2032 mpp = &((*mpp)->m_next);
2033 *mpp = recm;
2034 if (slp->ns_flag & SLP_LASTFRAG) {
2035 if (slp->ns_recend)
2036 slp->ns_recend->m_nextpkt = slp->ns_frag;
2037 else
2038 slp->ns_rec = slp->ns_frag;
2039 slp->ns_recend = slp->ns_frag;
2040 slp->ns_frag = (struct mbuf *)0;
2041 }
2042 }
2043 }
2044
2045
2046
2047
2048 int
2049 nfsrv_dorec(slp, nfsd, ndp)
2050 struct nfssvc_sock *slp;
2051 struct nfsd *nfsd;
2052 struct nfsrv_descript **ndp;
2053 {
2054 struct mbuf *m, *nam;
2055 struct nfsrv_descript *nd;
2056 int error;
2057
2058 *ndp = NULL;
2059 if ((slp->ns_flag & SLP_VALID) == 0 ||
2060 (m = slp->ns_rec) == (struct mbuf *)0)
2061 return (ENOBUFS);
2062 slp->ns_rec = m->m_nextpkt;
2063 if (slp->ns_rec)
2064 m->m_nextpkt = (struct mbuf *)0;
2065 else
2066 slp->ns_recend = (struct mbuf *)0;
2067 if (m->m_type == MT_SONAME) {
2068 nam = m;
2069 m = m->m_next;
2070 nam->m_next = NULL;
2071 } else
2072 nam = NULL;
2073 MALLOC(nd, struct nfsrv_descript *, sizeof (struct nfsrv_descript),
2074 M_NFSRVDESC, M_WAITOK);
2075 nfs_realign(&m, 10 * NFSX_UNSIGNED);
2076 nd->nd_md = nd->nd_mrep = m;
2077 nd->nd_nam2 = nam;
2078 nd->nd_dpos = mtod(m, caddr_t);
2079 error = nfs_getreq(nd, nfsd, TRUE);
2080 if (error) {
2081 m_freem(nam);
2082 free((caddr_t)nd, M_NFSRVDESC);
2083 return (error);
2084 }
2085 *ndp = nd;
2086 nfsd->nfsd_nd = nd;
2087 return (0);
2088 }
2089
2090
2091
2092
2093
2094
2095
2096 void
2097 nfsrv_wakenfsd(slp)
2098 struct nfssvc_sock *slp;
2099 {
2100 struct nfsd *nd;
2101
2102 if ((slp->ns_flag & SLP_VALID) == 0)
2103 return;
2104 for (nd = TAILQ_FIRST(&nfsd_head); nd != NULL;
2105 nd = TAILQ_NEXT(nd, nfsd_chain)) {
2106 if (nd->nfsd_flag & NFSD_WAITING) {
2107 nd->nfsd_flag &= ~NFSD_WAITING;
2108 if (nd->nfsd_slp)
2109 panic("nfsd wakeup");
2110 slp->ns_sref++;
2111 nd->nfsd_slp = slp;
2112 wakeup((caddr_t)nd);
2113 return;
2114 }
2115 }
2116 slp->ns_flag |= SLP_DOREC;
2117 nfsd_head_flag |= NFSD_CHECKSLP;
2118 }
2119 #endif