/[pdpsoft]/trunk/grid-mw-security/ees/src/app/main.c
ViewVC logotype

Annotation of /trunk/grid-mw-security/ees/src/app/main.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1589 - (hide annotations) (download) (as text)
Wed Mar 24 16:09:58 2010 UTC (12 years, 6 months ago) by aramv
File MIME type: text/x-chdr
File size: 9537 byte(s)
Doing something with select and xacml_server_set_fd()
1 aramv 1589 #define _MULTI_THREADED
2     #define NUM_THREADS 2
3    
4     #include <stdio.h>
5     #include <stdlib.h>
6     #include <pthread.h>
7    
8     #include <unistd.h>
9     #include <netinet/in.h>
10     #include <sys/types.h>
11     #include <sys/socket.h>
12     #include <string.h>
13     #include <netdb.h>
14     #include <arpa/inet.h>
15    
16     #include "ees_eics.h"
17     #include "xacml.h"
18     #include "xacml_server.h"
19     #include "eef_library.h"
20    
21     #define PORT 1234
22     #define BACKLOG 10
23    
24     typedef enum xacml_server_state_wrapper_s {
25     READY,
26     BUSY
27     } xacml_server_state_wrapper_t;
28    
29     typedef struct xacml_server_wrapper_s {
30     xacml_server_state_wrapper_t state;
31     xacml_server_t server;
32     } xacml_server_wrapper_t;
33    
34     pthread_t threads[NUM_THREADS]; /* thread pool */
35     xacml_server_wrapper_t* xacml_threads[NUM_THREADS]; /* xacml 'server' pool */
36     char* config_file_path; /* config file path */
37     int listen_socket;
38     int fdmax;
39     fd_set master;
40     fd_set read_fds;
41     struct timeval timeout;
42    
43     int process_xacml(int);
44     xacml_server_wrapper_t* make_xacml_server(void);
45     xacml_server_wrapper_t* get_ready_xacml_server(void);
46     char *get_ip_str(const struct sockaddr *sa);
47     void signal_handler(int sig);
48     int bind_socket(void);
49     EES_RC ees_stop(void);
50     EES_RC ees_start(void);
51     EES_RC ees_loop(void);
52     EES_RC add_dummy_aos_obligation(void);
53    
54     xacml_server_wrapper_t* make_xacml_server(void){
55     xacml_server_wrapper_t* server_wrapper;
56     xacml_server_t server;
57     xacml_init(); /* if you look at the code, you'll see this function is empty */
58     if(xacml_server_init(&server, ees_xacml_authorize, NULL) == XACML_RESULT_SUCCESS){
59     /* Set the I/O handler object */
60     /* xacml_server_set_io_descriptor(server, &xacml_io_ssl_descriptor); */
61     /* start server and block further execution */
62     if((server_wrapper = calloc(1, sizeof(xacml_server_wrapper_t)))){
63     server_wrapper->state = READY;
64     server_wrapper->server = server;
65     }
66     printf("Server initialized at: %p\n", server);
67     }
68     return server_wrapper;
69     }
70    
71     xacml_server_wrapper_t* get_ready_xacml_server(void){
72     int i;
73     xacml_server_wrapper_t* server_wrapper = NULL;
74     xacml_server_t server;
75     for(i = 0; i < NUM_THREADS; i++){
76     server_wrapper = (xacml_server_wrapper_t*) xacml_threads[i];
77     if(server_wrapper->state == READY){
78     break;
79     }
80     }
81     return server_wrapper;
82     }
83    
84     /**
85     Convert a struct sockaddr address to a string, IPv4 and IPv6.
86     Adapted from: http://beej.us/guide/bgnet/output/html/multipage/inet_ntopman.html
87     */
88     char *get_ip_str(const struct sockaddr *sa){
89     char* s;
90     switch(sa->sa_family) {
91     case AF_INET:
92     if((s = calloc(1, INET6_ADDRSTRLEN))){
93     inet_ntop(AF_INET, &(((const struct sockaddr_in *)sa)->sin_addr), s, INET6_ADDRSTRLEN);
94     }
95     break;
96     case AF_INET6:
97     if((s = calloc(1, INET_ADDRSTRLEN))){
98     inet_ntop(AF_INET6, &(((const struct sockaddr_in6 *)sa)->sin6_addr), s, INET_ADDRSTRLEN);
99     }
100     break;
101     default:
102     strncpy(s, "Unknown", strlen("Unknown")+1);
103     }
104     return s;
105     }
106    
107     int bind_socket(void){
108     int sockfd; // listen on sock_fd, new connection on new_fd
109     struct addrinfo hints, *servinfo, *p;
110     int reuse_addr=1;
111     char port_str[7];
112     int rv;
113    
114     sprintf(port_str, "%i", PORT);
115    
116     memset(&hints, 0, sizeof hints);
117     hints.ai_family = AF_UNSPEC;
118     hints.ai_socktype = SOCK_STREAM;
119     hints.ai_flags = AI_PASSIVE; // use my IP
120    
121     if ((rv = getaddrinfo(NULL, port_str, &hints, &servinfo)) != 0) {
122     fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
123     return 1;
124     }
125    
126     // loop through all the results and bind to the first we can
127     for(p = servinfo; p != NULL; p = p->ai_next) {
128     if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) {
129     perror("server: socket");
130     continue;
131     }
132     if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &reuse_addr, sizeof(reuse_addr)) == -1) {
133     perror("setsockopt");
134     }
135     if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
136     close(sockfd);
137     perror("server: bind");
138     continue;
139     }
140    
141     break;
142     }
143    
144     if (p == NULL) {
145     fprintf(stderr, "server: failed to bind\n");
146     return 2;
147     }
148     printf("Bound to: %s:%i\n", get_ip_str(servinfo->ai_addr), PORT);
149     freeaddrinfo(servinfo); // all done with this structure
150     return sockfd;
151     }
152    
153     void signal_handler(int sig){
154     switch(sig){
155     case SIGHUP:
156     eef_log(LOG_NOTICE, "Got SIGHUP - restart \n");
157     printf("Got SIGHUP - restart \n");
158     ees_stop();
159     ees_start();
160     ees_loop();
161     break;
162     case SIGTERM:
163     eef_log(LOG_NOTICE, "Got SIGTERM - shutting down\n");
164     printf("Got SIGTERM - shutting down\n");
165     ees_stop();
166     exit(0);
167     break;
168     }
169     }
170    
171     EES_RC add_dummy_aos_obligation(void){
172     aos_context_t* _context;
173     aos_attribute_t *_uid, *_gid;
174    
175     char* _uid_str = "1234";
176     char* _gid_str = "1234";
177    
178     /*fill aos */
179     _uid = createAttribute();
180     _gid = createAttribute();
181    
182     setAttributeId(_uid, "posix-uid");
183     setAttributeValue(_uid, _uid_str, strlen(_uid_str));
184     setAttributeId(_gid, "posix-gid");
185     setAttributeValue(_gid, _gid_str, strlen(_gid_str));
186    
187     if((_context = createContext(OBLIGATION)) != NULL){
188     setContextObligationId(_context, "uidgid");
189    
190     addAttribute(_context, _uid);
191     addAttribute(_context, _gid);
192    
193     addContext(_context);
194     }
195     return EES_SUCCESS;
196     }
197    
198     EES_RC ees_start(void){
199     long t; /* thread iterator */
200     /* reuse this part when implementing SIGHUP */
201     printf("Parsing config file %s\n", config_file_path);
202     if(EEF_Init(config_file_path, NULL, 0, NULL) == EES_FAILURE){
203     eef_log(LOG_ERR, "Failed to parse config file (%s), exiting...", config_file_path);
204     } else {
205     aos_dump_argslist();
206     aos_start_threading();
207     /*process_xacml(PORT);*/
208     /* start threading */
209     for(t=0; t < NUM_THREADS; t++){
210     printf("Creating thread %li!\n", t);
211     /*rc = pthread_create(&threads[t], NULL, (void*)(void*) EEF_Run, (void*)(t));*/
212     /*rc = pthread_create(&threads[t], NULL, (void*)(void*) process_xacml, (void*)(PORT));*/
213     /*rc = pthread_join(threads[t], &status);*/
214     xacml_threads[t] = make_xacml_server();
215    
216     /**//*Fire up SAML2-XACML2 */
217     /**//*process_xacml(PORT);*/
218    
219     }
220     }
221     return EES_SUCCESS;
222     }
223    
224     EES_RC ees_loop(void){
225     int i, j;
226     socklen_t addrlen;
227     struct sockaddr_storage remoteaddr;
228     int newfd;
229     int nbytes;
230     char buf[256];
231     xacml_server_wrapper_t* ready_server_wrapper = NULL;
232     while(1){
233     read_fds = master;
234     if(select(fdmax+1, &read_fds, NULL, NULL, NULL) >= 0){
235     for(i = 0; i <= fdmax; i++){
236     if(FD_ISSET(i, &read_fds)){
237     /*printf("We got one!\n");*/
238     if(i == listen_socket){
239     ready_server_wrapper = get_ready_xacml_server();
240     // handle new connection
241     printf("Got new connection\n");
242     addrlen = sizeof(remoteaddr);
243     /*newfd = accept(listen_socket, (struct sockaddr*) &remoteaddr, &addrlen);*/
244     /*if(newfd == -1){*/
245     /*printf("Bug!\n");*/
246     /*} else {*/
247     FD_SET(newfd, &master);
248     if(newfd > fdmax){
249     fdmax = newfd;
250     }
251     printf("ees: new connection from %s on socket %d\n", get_ip_str((struct sockaddr*) &remoteaddr), newfd);
252     if(xacml_server_set_fd(ready_server_wrapper->server, newfd) == XACML_RESULT_SUCCESS){
253     xacml_server_start(ready_server_wrapper->server);
254     }
255    
256     /*}*/
257     } else {
258     // handle data from connected client
259     if ((nbytes = recv(i, buf, sizeof(buf), 0)) <= 0) {
260     // got error or connection closed by client
261     if (nbytes == 0) {
262     // connection closed
263     printf("ees: socket %d hung up\n", i);
264     } else {
265     perror("recv");
266     }
267     close(i); // bye!
268     FD_CLR(i, &master); // remove from master set
269     } else {
270     // we got some data from a client
271     for(j = 0; j <= fdmax; j++) {
272     // send to everyone!
273     if (FD_ISSET(j, &master)) {
274     // except the listener and ourselves
275     if (j != listen_socket && j != i) {
276     if (send(j, buf, nbytes, 0) == -1) {
277     perror("send");
278     }
279     }
280     }
281     }
282     }
283     }
284     }
285     }
286     }
287     }
288     return EES_SUCCESS;
289     }
290    
291     EES_RC ees_stop(void){
292     long t; /* thread iterator */
293     AOS_Clean();
294     EEF_Term();
295     for(t=0; t < NUM_THREADS; t++){
296     /*xacml_server_destroy(server);*/
297     printf("XACML service destroyed\n");
298     }
299     fflush(stdout);
300     fflush(stderr);
301     return EES_SUCCESS;
302     }
303    
304     int main (int argc, char* argv[]){
305     int rc; /* return code from pthread functions */
306     void* status; /* thread join status */
307    
308     if(argc > 1){
309     config_file_path = argv[1];
310     } else {
311     config_file_path = "examples/example_1.pdl";
312     }
313    
314     listen_socket = bind_socket();
315     ees_start();
316    
317     #if !ENABLE_DEBUG
318     EEF_Daemonize();
319     #endif
320    
321     signal(SIGHUP, signal_handler); /* catch hangup signal */
322     signal(SIGTERM, signal_handler); /* catch kill signal */
323     FD_ZERO(&master);
324     FD_ZERO(&read_fds);
325    
326     if(listen(listen_socket, BACKLOG) == 0){
327     printf("Ready.\n");
328     FD_SET(listen_socket, &master);
329     fdmax = listen_socket;
330     ees_loop();
331     } else {
332     eef_log(LOG_ERR, "Error listening: %s\n", strerror(errno));
333     }
334    
335     printf("terminated!\n");
336    
337     aos_dump_argslist();
338     /*pthread_exit(NULL);*/
339    
340     return 0;
341     }
342    

grid.support@nikhef.nl
ViewVC Help
Powered by ViewVC 1.1.28