3 #include <event2/event.h>
10 #include <trp_internal.h>
11 #include <tr_config.h>
16 /* hold a trps instance and a config manager */
17 struct tr_trps_event_cookie {
23 /* callback to schedule event to process messages */
24 static void tr_trps_mq_cb(TR_MQ *mq, void *arg)
26 struct event *mq_ev=(struct event *)arg;
27 event_active(mq_ev, 0, 0);
30 static int tr_trps_req_handler (TRPS_INSTANCE *trps,
36 return -1; /* not handling anything right now */
40 static int tr_trps_gss_handler(gss_name_t client_name, gss_buffer_t gss_name,
44 struct tr_trps_event_cookie *cookie=(struct tr_trps_event_cookie *)cookie_in;
45 TRPS_INSTANCE *trps = cookie->trps;
46 TR_CFG_MGR *cfg_mgr = cookie->cfg_mgr;
47 TR_NAME name={gss_name->value, gss_name->length};
49 tr_debug("tr_trps_gss_handler()");
51 if ((!client_name) || (!gss_name) || (!trps) || (!cfg_mgr)) {
52 tr_debug("tr_trps_gss_handler: Bad parameters.");
56 /* look up the RP client matching the GSS name */
57 if ((NULL == (rp = tr_rp_client_lookup(cfg_mgr->active->rp_clients, &name)))) {
58 tr_debug("tr_trps_gss_handler: Unknown GSS name %.*s", name.len, name.buf);
62 /*trps->rp_gss = rp;*/
63 tr_debug("Client's GSS Name: %.*s", name.len, name.buf);
68 /* data passed to thread */
73 /* thread to handle GSS connections to peers */
74 static void *tr_trps_conn_thread(void *arg)
76 TALLOC_CTX *tmp_ctx=talloc_new(NULL);
77 struct thread_data *thread_data=talloc_get_type_abort(arg, struct thread_data);
78 TRP_CONNECTION *conn=thread_data->conn;
79 TRPS_INSTANCE *trps=thread_data->trps;
82 tr_debug("tr_trps_conn_thread: started");
83 /* try to establish a GSS context */
84 if (0!=trp_connection_auth(conn, trps->auth_handler, trps->cookie)) {
85 tr_notice("tr_trps_conn_thread: failed to authorize connection");
88 tr_notice("tr_trps_conn_thread: authorized connection");
90 msg=tr_mq_msg_new(tmp_ctx);
92 tr_err("tr_trps_conn_thread: error allocating TR_MQ_MSG");
94 trps_mq_append(trps, msg);
96 tr_debug("tr_trps_conn_thread: exit");
101 /* called when a connection to the TRPS port is received */
102 static void tr_trps_event_cb(int listener, short event, void *arg)
104 TALLOC_CTX *tmp_ctx=talloc_new(NULL);
105 TRPS_INSTANCE *trps = talloc_get_type_abort(arg, TRPS_INSTANCE); /* aborts on wrong type */
106 TRP_CONNECTION *conn=NULL;
107 TR_NAME *gssname=NULL;
109 struct thread_data *thread_data;
111 if (0==(event & EV_READ)) {
112 tr_debug("tr_trps_event_cb: unexpected event on TRPS socket (event=0x%X)", event);
114 /* create a thread to handle this connection */
115 asprintf(&name, "trustrouter@%s", trps->hostname);
116 gssname=tr_new_name(name);
117 free(name); name=NULL;
118 conn=trp_connection_accept(tmp_ctx, listener, gssname, trps_auth_cb, NULL, trps);
120 /* need to monitor this fd and trigger events when read becomes possible */
121 thread_data=talloc(conn, struct thread_data);
122 if (thread_data==NULL) {
123 tr_err("tr_trps_event_cb: unable to allocate thread_data");
124 talloc_free(tmp_ctx);
127 thread_data->conn=conn;
128 thread_data->trps=trps;
129 pthread_create(conn->thread, NULL, tr_trps_conn_thread, thread_data);
130 pthread_detach(*(conn->thread)); /* we will not rejoin the thread */
131 trps_add_connection(trps, conn); /* remember the connection */
134 talloc_free(tmp_ctx);
137 static void tr_trps_process_mq(int socket, short event, void *arg)
139 TRPS_INSTANCE *trps=talloc_get_type_abort(arg, TRPS_INSTANCE);
142 tr_debug("tr_trps_process_mw: starting");
143 msg=trps_mq_pop(trps);
145 tr_debug("tr_trps_process_mq: received message");
147 msg=trps_mq_pop(trps);
149 tr_debug("tr_trps_process_mw: ending");
152 TR_TRPS_EVENTS *tr_trps_events_new(TALLOC_CTX *mem_ctx)
154 TR_TRPS_EVENTS *ev=talloc(mem_ctx, TR_TRPS_EVENTS);
156 ev->listen_ev=talloc(ev, struct tr_socket_event);
158 if (ev->listen_ev==NULL) {
166 /* Configure the trps instance and set up its event handler.
167 * Returns 0 on success, nonzero on failure. Results in
168 * trps_ev, which should be allocated by caller. */
169 int tr_trps_event_init(struct event_base *base,
172 TR_TRPS_EVENTS *trps_ev)
174 TALLOC_CTX *tmp_ctx=talloc_new(NULL);
175 struct tr_socket_event *listen_ev=NULL;
176 struct tr_trps_event_cookie *cookie;
179 if (trps_ev == NULL) {
180 tr_debug("tr_trps_event_init: Null trps_ev.");
185 /* get convenient handles */
186 listen_ev=trps_ev->listen_ev;
188 /* Create the cookie for callbacks. It is part of the trps context, so it will
189 * be cleaned up when trps is freed by talloc_free. */
190 cookie=talloc(tmp_ctx, struct tr_trps_event_cookie);
191 if (cookie == NULL) {
192 tr_debug("tr_trps_event_init: Unable to allocate cookie.");
197 cookie->cfg_mgr=cfg_mgr;
198 talloc_steal(trps, cookie);
200 /* get a trps listener */
201 listen_ev->sock_fd=trps_get_listener(trps,
204 cfg_mgr->active->internal->hostname,
205 cfg_mgr->active->internal->trps_port,
207 if (listen_ev->sock_fd < 0) {
208 tr_crit("Error opening TRP server socket.");
214 listen_ev->ev=event_new(base,
219 event_add(listen_ev->ev, NULL);
221 /* now set up message queue processing event, only triggered by
223 trps_ev->mq_ev=event_new(base,
228 tr_mq_set_notify_cb(trps->mq, tr_trps_mq_cb, trps_ev->mq_ev);
231 talloc_free(tmp_ctx);