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

Diff of /radius/radiusd/forward.c

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

revision 1.1 by gray, Fri Oct 31 09:14:54 2003 UTC revision 1.2 by gray, Fri Oct 31 13:09:46 2003 UTC
# Line 26  Line 26 
26  #include <netdb.h>  #include <netdb.h>
27  #include <radiusd.h>  #include <radiusd.h>
28    
 struct forward_data {  
         int type;  
         struct sockaddr_in addr;  
 };  
   
29  struct request_data {  struct request_data {
30          int type;          int type;
31          void *ptr;          RADIUS_REQ *req;
         size_t size;  
32  };  };
33    
34  static int forward_fd = -1;  static int forward_fd = -1;
# Line 43  static RAD_LIST *forward_list; Line 37  static RAD_LIST *forward_list;
37  static void  static void
38  add_forward(int type, UINT4 ip, int port)  add_forward(int type, UINT4 ip, int port)
39  {  {
40          struct forward_data *fp;          RADIUS_SERVER *srv;
41    
42          if (!forward_list) {          if (!forward_list) {
43                  forward_list = list_create();                  forward_list = list_create();
# Line 51  add_forward(int type, UINT4 ip, int port Line 45  add_forward(int type, UINT4 ip, int port
45                          return; /* FIXME */                          return; /* FIXME */
46          }          }
47                                    
48          fp = emalloc(sizeof(*fp));          srv = emalloc(sizeof(*srv));
49          fp->type = type;          srv->name = NULL;
50          fp->addr.sin_addr.s_addr = htonl(ip);          srv->addr = ip;
51          fp->addr.sin_port = htons(port);          srv->port[type] = port;
52          list_append(forward_list, fp);          list_append(forward_list, srv);
53  }  }
54    
55  static int  static int
# Line 93  rad_cfg_forward_acct(int argc, cfg_value Line 87  rad_cfg_forward_acct(int argc, cfg_value
87  {  {
88          return rad_cfg_forward(argc, argv, R_ACCT, acct_port);          return rad_cfg_forward(argc, argv, R_ACCT, acct_port);
89  }  }
90            
91    
92    static void
93    forward_data(RADIUS_SERVER *srv, int type, void *data, size_t size)
94    {
95            int rc;
96            struct sockaddr_in addr;
97    
98            addr.sin_family = AF_INET;
99            addr.sin_addr.s_addr = htonl(srv->addr);
100            addr.sin_port = htons(srv->port[type]);
101    
102            rc = sendto(forward_fd, data, size, 0,
103                        (struct sockaddr *)&addr, sizeof(addr));
104            if (rc < 0) {
105                    char buffer[DOTTED_QUAD_LEN];
106    
107                    radlog(L_ERR|L_PERROR,
108                           _("Can't forward to %s:%d"),
109                           ip_iptostr(srv->addr, buffer),
110                           srv->port[type]);
111            }
112    }
113    
114    static void
115    forward_request_recode(RADIUS_SERVER *srv, struct request_data *r)
116    {
117            VALUE_PAIR *vp;
118            void *pdu;
119            size_t size;
120    
121            vp = proxy_request_recode(r->req, srv->secret, r->req->vector);
122            size = rad_create_pdu(&pdu, r->req->code,
123                                  rad_clt_message_id(srv),
124                                  r->req->vector,
125                                  srv->secret,
126                                  vp,
127                                  NULL);
128            avl_free(vp);
129            forward_data(srv, r->type, pdu, size);
130            efree(pdu);
131    }
132    
133  static int  static int
134  forwarder(void *item, void *data)  forwarder(void *item, void *data)
135  {  {
136          struct forward_data *f = item;          RADIUS_SERVER *srv = item;
137          struct request_data *r = data;          struct request_data *r = data;
138          int rc;          int rc;
139    
140          if (f->type == r->type) {          if (srv->port[r->type] != 0) {
141                  rc = sendto(forward_fd, r->ptr, r->size, 0,                  VALUE_PAIR *vp = NULL, *plist;
142                              (struct sockaddr *)&f->addr, sizeof(f->addr));                  void *pdu;
143                  if (rc < 0) {                  size_t size;
144                          char buffer[DOTTED_QUAD_LEN];                  int id;
145                          ip_iptostr(ntohl(f->addr.sin_addr.s_addr), buffer);                  u_char *secret;
146                          radlog(L_ERR|L_PERROR,                  
147                                 _("Can't send to %s:%d"),                  if (srv->secret) {
148                                 buffer, ntohs(f->addr.sin_port));                          secret = srv->secret;
149                            vp = proxy_request_recode(r->req, secret,
150                                                      r->req->vector);
151                            plist = vp;
152                            id = rad_clt_message_id(srv);
153                    } else {
154                            secret = r->req->secret;
155                            plist = r->req->request;
156                            id = r->req->id;
157                  }                  }
158                    size = rad_create_pdu(&pdu,
159                                          r->req->code,
160                                          id,
161                                          r->req->vector,
162                                          secret,
163                                          plist,
164                                          NULL);
165                    avl_free(vp);
166                    forward_data(srv, r->type, pdu, size);
167                    efree(pdu);
168          }          }
169          return 0;          return 0;
170  }  }
# Line 130  forward_before_config_hook(void *a ARG_U Line 184  forward_before_config_hook(void *a ARG_U
184          list_destroy(&forward_list, free_mem, NULL);          list_destroy(&forward_list, free_mem, NULL);
185  }  }
186    
187    static int
188    fixup_forward_server(void *item, void *data)
189    {
190            RADIUS_SERVER *srv = item;
191            CLIENT *cl = client_lookup_ip(srv->addr);
192            if (!cl) {
193                    char buffer[DOTTED_QUAD_LEN];
194                    radlog(L_NOTICE,
195                           _("Forwarding host %s not listed in clients"),
196                           ip_iptostr(srv->addr, buffer));
197            } else
198                    srv->secret = cl->secret;
199            return 0;
200    }
201    
202    static void
203    forward_after_config_hook(void *a ARG_UNUSED, void *b ARG_UNUSED)
204    {
205            struct sockaddr_in s;
206            
207            if (list_count(forward_list) == 0)
208                    return;
209            
210            forward_fd = socket(PF_INET, SOCK_DGRAM, 0);
211    
212            if (forward_fd == -1) {
213                    radlog(L_ERR|L_PERROR,
214                           _("Can't open forwarding socket"));
215                    return;
216            }
217    
218            memset (&s, 0, sizeof (s));
219            s.sin_family = AF_INET;
220            s.sin_addr.s_addr = htonl(ref_ip);
221            s.sin_port = 0;
222            if (bind(forward_fd, (struct sockaddr*)&s, sizeof (s)) < 0)
223                    radlog(L_ERR|L_PERROR, _("Can't bind forwarding socket"));
224            
225            list_iterate(forward_list, fixup_forward_server, NULL);
226    }
227    
228  void  void
229  forward_init()  forward_init()
230  {  {
231          radiusd_set_preconfig_hook(forward_before_config_hook, NULL, 0);          radiusd_set_preconfig_hook(forward_before_config_hook, NULL, 0);
232            radiusd_set_postconfig_hook(forward_after_config_hook, NULL, 0);
233  }  }
234    
235  void  void
236  forward_request(int type, void *data, size_t size)  forward_request(int type, RADIUS_REQ *req)
237  {  {
238          struct request_data rd;          struct request_data rd;
239    
240          if (!forward_list)          if (!forward_list || forward_fd == -1)
241                  return;                  return;
242                    
243          if (forward_fd == -1) {          switch (type) {
244                  forward_fd = socket(PF_INET, SOCK_DGRAM, 0);          case R_AUTH:
245            case R_ACCT:
246                  if (forward_fd == -1) {                  break;
247                          radlog(L_ERR|L_PERROR,          default:
248                                 _("Can't open forwarding socket"));                  return;
                         return;  
                 }  
249          }          }
250            
251          rd.type = type;          rd.type = type;
252          rd.ptr = data;          rd.req = req;
         rd.size = size;  
253          list_iterate(forward_list, forwarder, &rd);          list_iterate(forward_list, forwarder, &rd);
254  }  }
255    

Legend:
Removed from v.1.1  
changed lines
  Added in v.1.2

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