1 |
/* Main server loop for nfs server. |
/* loop.c - Main server loop for nfs server. |
2 |
Copyright (C) 1996,98,2002 Free Software Foundation, Inc. |
Copyright (C) 1996,98,2002 Free Software Foundation, Inc. |
3 |
Written by Michael I. Bushnell, p/BSG. |
Written by Michael I. Bushnell, p/BSG. |
4 |
|
|
55 |
socklen_t addrlen; |
socklen_t addrlen; |
56 |
int cc; |
int cc; |
57 |
|
|
58 |
bzero (&fakec, sizeof (struct cache_handle)); |
memset (&fakec, 0, sizeof (struct cache_handle)); |
59 |
|
|
60 |
for (;;) |
for (;;) |
61 |
{ |
{ |
64 |
addrlen = sizeof (struct sockaddr_in); |
addrlen = sizeof (struct sockaddr_in); |
65 |
cc = recvfrom (fd, buf, MAXIOSIZE, 0, &sender, &addrlen); |
cc = recvfrom (fd, buf, MAXIOSIZE, 0, &sender, &addrlen); |
66 |
if (cc == -1) |
if (cc == -1) |
67 |
continue; /* ignore errors */ |
continue; /* Ignore errors. */ |
68 |
xid = *p++; |
xid = *(p++); |
69 |
|
|
70 |
/* Ignore things that aren't proper RPCs. */ |
/* Ignore things that aren't proper RPCs. */ |
71 |
if (ntohl (*p++) != CALL) |
if (ntohl (*p) != CALL) |
72 |
continue; |
continue; |
73 |
|
p++; |
74 |
|
|
75 |
cr = check_cached_replies (xid, &sender); |
cr = check_cached_replies (xid, &sender); |
76 |
if (cr->data) |
if (cr->data) |
77 |
/* This transacation has already completed */ |
/* This transacation has already completed. */ |
78 |
goto repost_reply; |
goto repost_reply; |
79 |
|
|
80 |
r = (int *) rbuf = malloc (MAXIOSIZE); |
r = (int *) rbuf = malloc (MAXIOSIZE); |
81 |
|
|
82 |
if (ntohl (*p++) != RPC_MSG_VERSION) |
if (ntohl (*p) != RPC_MSG_VERSION) |
83 |
{ |
{ |
84 |
/* Reject RPC */ |
/* Reject RPC. */ |
85 |
*r++ = xid; |
*(r++) = xid; |
86 |
*r++ = htonl (REPLY); |
*(r++) = htonl (REPLY); |
87 |
*r++ = htonl (MSG_DENIED); |
*(r++) = htonl (MSG_DENIED); |
88 |
*r++ = htonl (RPC_MISMATCH); |
*(r++) = htonl (RPC_MISMATCH); |
89 |
*r++ = htonl (RPC_MSG_VERSION); |
*(r++) = htonl (RPC_MSG_VERSION); |
90 |
*r++ = htonl (RPC_MSG_VERSION); |
*(r++) = htonl (RPC_MSG_VERSION); |
91 |
goto send_reply; |
goto send_reply; |
92 |
} |
} |
93 |
|
p++; |
94 |
|
|
95 |
program = ntohl (*p++); |
program = ntohl (*p); |
96 |
|
p++; |
97 |
switch (program) |
switch (program) |
98 |
{ |
{ |
99 |
case MOUNTPROG: |
case MOUNTPROG: |
112 |
break; |
break; |
113 |
|
|
114 |
default: |
default: |
115 |
/* Program unavailable */ |
/* Program unavailable. */ |
116 |
*r++ = xid; |
*(r++) = xid; |
117 |
*r++ = htonl (REPLY); |
*(r++) = htonl (REPLY); |
118 |
*r++ = htonl (MSG_ACCEPTED); |
*(r++) = htonl (MSG_ACCEPTED); |
119 |
*r++ = htonl (AUTH_NULL); |
*(r++) = htonl (AUTH_NULL); |
120 |
*r++ = htonl (0); |
*(r++) = htonl (0); |
121 |
*r++ = htonl (PROG_UNAVAIL); |
*(r++) = htonl (PROG_UNAVAIL); |
122 |
goto send_reply; |
goto send_reply; |
123 |
} |
} |
124 |
|
|
125 |
if (ntohl (*p++) != version) |
if (ntohl (*p) != version) |
126 |
{ |
{ |
127 |
/* Program mismatch */ |
/* Program mismatch. */ |
128 |
*r++ = xid; |
*(r++) = xid; |
129 |
*r++ = htonl (REPLY); |
*(r++) = htonl (REPLY); |
130 |
*r++ = htonl (MSG_ACCEPTED); |
*(r++) = htonl (MSG_ACCEPTED); |
131 |
*r++ = htonl (AUTH_NULL); |
*(r++) = htonl (AUTH_NULL); |
132 |
*r++ = htonl (0); |
*(r++) = htonl (0); |
133 |
*r++ = htonl (PROG_MISMATCH); |
*(r++) = htonl (PROG_MISMATCH); |
134 |
*r++ = htonl (version); |
*(r++) = htonl (version); |
135 |
*r++ = htonl (version); |
*(r++) = htonl (version); |
136 |
goto send_reply; |
goto send_reply; |
137 |
} |
} |
138 |
|
p++; |
139 |
|
|
140 |
procedure = htonl (*p++); |
procedure = htonl (*p); |
141 |
|
p++; |
142 |
if (procedure < table->min |
if (procedure < table->min |
143 |
|| procedure > table->max |
|| procedure > table->max |
144 |
|| table->procs[procedure - table->min].func == 0) |
|| table->procs[procedure - table->min].func == 0) |
145 |
{ |
{ |
146 |
/* Procedure unavailable */ |
/* Procedure unavailable. */ |
147 |
*r++ = xid; |
*(r++) = xid; |
148 |
*r++ = htonl (REPLY); |
*(r++) = htonl (REPLY); |
149 |
*r++ = htonl (MSG_ACCEPTED); |
*(r++) = htonl (MSG_ACCEPTED); |
150 |
*r++ = htonl (AUTH_NULL); |
*(r++) = htonl (AUTH_NULL); |
151 |
*r++ = htonl (0); |
*(r++) = htonl (0); |
152 |
*r++ = htonl (PROC_UNAVAIL); |
*(r++) = htonl (PROC_UNAVAIL); |
153 |
*r++ = htonl (table->min); |
*(r++) = htonl (table->min); |
154 |
*r++ = htonl (table->max); |
*(r++) = htonl (table->max); |
155 |
goto send_reply; |
goto send_reply; |
156 |
} |
} |
157 |
proc = &table->procs[procedure - table->min]; |
proc = &table->procs[procedure - table->min]; |
177 |
} |
} |
178 |
} |
} |
179 |
|
|
180 |
/* Fill in beginning of reply */ |
/* Fill in beginning of reply. */ |
181 |
*r++ = xid; |
*(r++) = xid; |
182 |
*r++ = htonl (REPLY); |
*(r++) = htonl (REPLY); |
183 |
*r++ = htonl (MSG_ACCEPTED); |
*(r++) = htonl (MSG_ACCEPTED); |
184 |
*r++ = htonl (AUTH_NULL); |
*(r++) = htonl (AUTH_NULL); |
185 |
*r++ = htonl (0); |
*(r++) = htonl (0); |
186 |
*r++ = htonl (SUCCESS); |
*(r++) = htonl (SUCCESS); |
187 |
if (!proc->process_error) |
if (!proc->process_error) |
188 |
/* The function does its own error processing, |
/* The function does its own error processing, and we ignore |
189 |
and we ignore its return value. */ |
its return value. */ |
190 |
(void) (*proc->func) (c, p, &r, version); |
(void) (*proc->func) (c, p, &r, version); |
191 |
else |
else |
192 |
{ |
{ |
193 |
if (c) |
if (c) |
194 |
{ |
{ |
195 |
/* Assume success for now and patch it later if necessary */ |
/* Assume success for now and patch it later if necessary. */ |
196 |
int *errloc = r; |
int *errloc = r; |
197 |
*r++ = htonl (0); |
*(r++) = htonl (0); |
198 |
/* Call processing function, its output after error code. */ |
/* Call processing function, its output after error code. */ |
199 |
err = (*proc->func) (c, p, &r, version); |
err = (*proc->func) (c, p, &r, version); |
200 |
if (err) |
if (err) |
201 |
{ |
{ |
202 |
r = errloc; /* Back up, patch error code, discard rest. */ |
r = errloc; /* Back up, patch error code, discard rest. */ |
203 |
*r++ = htonl (nfs_error_trans (err, version)); |
*(r++) = htonl (nfs_error_trans (err, version)); |
204 |
} |
} |
205 |
} |
} |
206 |
else |
else |
207 |
*r++ = htonl (nfs_error_trans (ESTALE, version)); |
*(r++) = htonl (nfs_error_trans (ESTALE, version)); |
208 |
} |
} |
209 |
|
|
210 |
cred_rele (cred); |
cred_rele (cred); |
217 |
|
|
218 |
repost_reply: |
repost_reply: |
219 |
sendto (fd, cr->data, cr->len, 0, |
sendto (fd, cr->data, cr->len, 0, |
220 |
(struct sockaddr *)&sender, addrlen); |
(struct sockaddr *) &sender, addrlen); |
221 |
release_cached_reply (cr); |
release_cached_reply (cr); |
222 |
} |
} |
223 |
} |
} |