/[radius]/radius/radiusd/request.c
ViewVC logotype

Diff of /radius/radiusd/request.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.26 by gray, Fri Apr 18 05:27:10 2003 UTC revision 1.27 by gray, Fri Apr 25 22:50:09 2003 UTC
# Line 26  Line 26 
26  #include <radsql.h>  #include <radsql.h>
27  #include <list.h>  #include <list.h>
28    
29    extern int spawn_flag; /* FIXME */
30  struct request_class request_class[] = {  struct request_class request_class[] = {
31          { "AUTH", 0, MAX_REQUEST_TIME, CLEANUP_DELAY,          { "AUTH", 0, MAX_REQUEST_TIME, CLEANUP_DELAY,
32            radius_req_decode,   /* Decoder */            radius_req_decode,   /* Decoder */
# Line 36  struct request_class request_class[] = { Line 37  struct request_class request_class[] = {
37            radius_req_drop,     /* Drop function */            radius_req_drop,     /* Drop function */
38            rad_sql_cleanup,  /* Cleanup function */            rad_sql_cleanup,  /* Cleanup function */
39            radius_req_failure,  /* Failure indicator */            radius_req_failure,  /* Failure indicator */
40              radius_req_update,
41          },          },
42          { "ACCT", 0, MAX_REQUEST_TIME, CLEANUP_DELAY,          { "ACCT", 0, MAX_REQUEST_TIME, CLEANUP_DELAY,
43            radius_req_decode,   /* Decoder */            radius_req_decode,   /* Decoder */
# Line 46  struct request_class request_class[] = { Line 48  struct request_class request_class[] = {
48            radius_req_drop,     /* Drop function */            radius_req_drop,     /* Drop function */
49            rad_sql_cleanup,  /* Cleanup function */            rad_sql_cleanup,  /* Cleanup function */
50            radius_req_failure,  /* Failure indicator */            radius_req_failure,  /* Failure indicator */
51          },            radius_req_update,
         { "PROXY",0, MAX_REQUEST_TIME, CLEANUP_DELAY,  
           radius_req_decode,   /* Decoder */  
           rad_proxy,        /* Handler */  
           radius_req_xmit,     /* Retransmitter */  
           radius_req_cmp,      /* Comparator */  
           radius_req_free,     /* Deallocator */    
           proxy_retry,      /* Drop function */  
           NULL,             /* Cleanup function */  
           NULL,             /* Failure indicator */  
52          },          },
53  #ifdef USE_SNMP  #ifdef USE_SNMP
54          { "SNMP", 0, MAX_REQUEST_TIME, 0,          { "SNMP", 0, MAX_REQUEST_TIME, 0,
# Line 67  struct request_class request_class[] = { Line 60  struct request_class request_class[] = {
60            snmp_req_drop,    /* Drop function */            snmp_req_drop,    /* Drop function */
61            NULL,             /* Cleanup function */            NULL,             /* Cleanup function */
62            NULL,             /* Failure indicator */            NULL,             /* Failure indicator */
63              NULL,
64          },          },
65  #endif  #endif
66          { NULL, }          { NULL, }
# Line 106  request_free(REQUEST *req) Line 100  request_free(REQUEST *req)
100          if (req) {          if (req) {
101                  request_class[req->type].free(req->data);                  request_class[req->type].free(req->data);
102                  efree(req->rawdata);                  efree(req->rawdata);
103                    efree(req->update);
104                  efree(req);                  efree(req);
105          }          }
106  }  }
# Line 130  request_xmit(REQUEST *req) Line 125  request_xmit(REQUEST *req)
125  }  }
126    
127  int  int
128  request_cmp(int type, void *a, void *b)  request_cmp(REQUEST *req, void *ptr)
129  {  {
130          return request_class[type].comp(a, b);          return request_class[req->type].comp(req->data, ptr);
131  }  }
132    
133  void  void
# Line 146  struct request_closure { Line 141  struct request_closure {
141          int type;                  /* Type of the request */          int type;                  /* Type of the request */
142          void *data;                /* Request contents */          void *data;                /* Request contents */
143          time_t curtime;            /* Current timestamp */          time_t curtime;            /* Current timestamp */
144            int (*handler)(REQUEST *); /* Handler function */
145          /* Output: */          /* Output: */
146            int state;                 /* Request compare state */
147            REQUEST *orig;             /* Matched request (for proxy requests) */
148          size_t request_count;      /* Total number of requests */          size_t request_count;      /* Total number of requests */
149          size_t request_type_count; /* Number of requests of this type */          size_t request_type_count; /* Number of requests of this type */
150  };  };
151    
152  static int  static int
153  _request_iterator(void *item, void *data)  _request_iterator(void *item, void *clos)
154  {  {
155          REQUEST *req = item;          REQUEST *req = item;
156          struct request_closure *rp = data;          struct request_closure *rp = clos;
157                    
158          if (req->status == RS_COMPLETED) {          if (req->status == RS_COMPLETED) {
159                  if (req->timestamp + request_class[req->type].cleanup_delay                  if (req->timestamp + request_class[req->type].cleanup_delay
# Line 166  _request_iterator(void *item, void *data Line 164  _request_iterator(void *item, void *data
164                          request_free(req);                          request_free(req);
165                          return 0;                          return 0;
166                  }                  }
167            } else if (req->status == RS_PROXY) {
168                    if (!spawn_flag || rpp_ready(req->child_id)) {
169                            debug(1, ("%s proxy reply. Process %lu",
170                                      request_class[req->type].name,
171                                      (u_long) req->child_id));
172                            (*rp->handler)(req);
173                            list_remove_current(request_list);
174                            request_free(req);
175                    } else if (req->timestamp + request_class[req->type].ttl
176                               <= rp->curtime) {
177                            radlog(L_NOTICE,
178                                   _("Proxy %s request expired in queue"),
179                                   request_class[req->type].name);
180                            list_remove_current(request_list);
181                            request_free(req);
182                    }
183          } else if (req->timestamp + request_class[req->type].ttl          } else if (req->timestamp + request_class[req->type].ttl
184                        <= rp->curtime) {                        <= rp->curtime) {
185    
# Line 178  _request_iterator(void *item, void *data Line 192  _request_iterator(void *item, void *data
192                  return 0;                  return 0;
193          }          }
194    
195          if (!rp->data)          if (req->type == rp->type)
196                    rp->request_type_count++;
197            rp->request_count++;
198    
199            if (rp->state != RCMP_NE)
200                  return 0;                  return 0;
201                    
202          if (req->type == rp->type          if (req->type == rp->type) {
203              && request_cmp(req->type, req->data, data) == 0) {                  rp->state = request_cmp(req, rp->data);
204                  /* This is a duplicate request. If it is already completed,                  switch (rp->state) {
205                     then hand it over to the child.                  case RCMP_EQ:
206                     Otherwise drop the request. */                          /* This is a duplicate request. If it is already
207                  if (req->status == RS_COMPLETED) {                             completed, hand it over to the child.
208                          if (radiusd_master())                             Otherwise drop the request. */
209                                  rpp_forward_request(req);                          if (req->status == RS_COMPLETED) {
210                          else                                  if (radiusd_master())
211                                  request_xmit(req);                                          rpp_forward_request(req);
212                                    else
213                  } else                                          request_xmit(req);
214                          request_drop(req->type, data, req->data, req->fd,                          } else
215                                       _("duplicate request"));                                  request_drop(req->type, rp->data,
216                  /* Indicate end of request processing */                                               req->data, req->fd,
217                  rp->data = NULL;                                               _("duplicate request"));
218                  return 0;                          break;
219          } else {  
220                  if (req->type == rp->type)                  case RCMP_PROXY:
221                          rp->request_type_count++;                          rp->orig = req;
222                  rp->request_count++;                          break;
223          }                  }
224            }
225            
226          return 0;          return 0;
227  }  }
228    
# Line 216  request_handle(REQUEST *req, int (*handl Line 236  request_handle(REQUEST *req, int (*handl
236                    
237          rc.type = req->type;          rc.type = req->type;
238          rc.data = req->data;          rc.data = req->data;
239            rc.orig = NULL;
240            rc.state = RCMP_NE;
241            rc.handler = handler;
242          time(&rc.curtime);          time(&rc.curtime);
243          rc.request_count = rc.request_type_count = 0;          rc.request_count = rc.request_type_count = 0;
244    
# Line 224  request_handle(REQUEST *req, int (*handl Line 247  request_handle(REQUEST *req, int (*handl
247          else          else
248                  list_iterate(request_list, _request_iterator, &rc);                  list_iterate(request_list, _request_iterator, &rc);
249    
250          if (!rc.data)          switch (rc.state) {
251            case RCMP_EQ: /* duplicate */
252                  return 1;                  return 1;
253    
254            case RCMP_PROXY:
255                    req->orig = rc.orig;
256                    req->child_id = rc.orig->child_id;
257                    if (!radiusd_master()) {
258                            debug(1, ("%s proxy reply. Process %lu",
259                                      request_class[req->type].name,
260                                      (u_long) req->child_id));
261                            (*handler)(req);
262                    } else {
263                            if (!spawn_flag || rpp_ready(req->child_id)) {
264                                    debug(1, ("%s proxy reply. Process %lu",
265                                              request_class[req->type].name,
266                                              (u_long) req->child_id));
267                                    (*handler)(req);
268                            } else {
269                                    req->status = RS_PROXY;
270                                    /* Add request to the queue */
271                                    debug(1, ("Proxy %s request %lu added to the list. %d requests held.",
272                                              request_class[req->type].name,
273                                              (u_long) req->child_id,
274                                              rc.request_count+1));
275                                    list_append(request_list, req);
276                                    return 0;
277                            }
278                    }
279                    return 1; /* Do not keep this request */
280            }
281                    
282          /* This is a new request */          /* This is a new request */
283          if (rc.request_count >= max_requests) {          if (rc.request_count >= max_requests) {
# Line 238  request_handle(REQUEST *req, int (*handl Line 290  request_handle(REQUEST *req, int (*handl
290                               _("too many requests of this type"));                               _("too many requests of this type"));
291                  return 1;                  return 1;
292          }          }
293            
294          /* Do we have free handlers? */          if (radiusd_master() && spawn_flag && !rpp_ready(0)) {
295          if (radiusd_master() && !rpp_ready()) {                  /* Do we have free handlers? */
296                  radlog(L_NOTICE, _("Maximum number of children active"));                  radlog(L_NOTICE, _("Maximum number of children active"));
297                  return 1;                  return 1;
298          }          }
299                            
300          /* Add request to the queue */          /* Add request to the queue */
301          debug(1, ("%s request %lu added to the list. %d requests held.",          debug(1, ("%s request %lu added to the list. %d requests held.",
302                    request_class[req->type].name,                    request_class[req->type].name,
303                    (u_long) req->child_id,                    (u_long) req->child_id,
304                    rc.request_count+1));                    rc.request_count+1));
305    
306          list_append(request_list, req);          if ((*handler)(req) == 0) {
307          return (*handler)(req);                  list_append(request_list, req);
308                    return 0;
309            }
310            return 1;
311  }  }
312    
313  void  void
314  request_set_status(pid_t pid, int status)  request_update(pid_t pid, int status, void *ptr)
315  {  {
316          REQUEST *p;          REQUEST *p;
317    
318            debug(100,("enter"));
319          for (p = list_first(request_list); p; p = list_next(request_list))          for (p = list_first(request_list); p; p = list_next(request_list))
320                  if (p->child_id == pid) {                  if (p->child_id == pid) {
321                          p->status = status;                          p->status = status;
322                            if (ptr && request_class[p->type].update)
323                                    request_class[p->type].update(p->data, ptr);
324                          break;                          break;
325                  }                  }
326            debug(100,("exit"));
327  }  }
328                                                    
329    

Legend:
Removed from v.1.26  
changed lines
  Added in v.1.27

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26