9 #include <trp_internal.h>
12 TRPS_INSTANCE *trps_new (TALLOC_CTX *mem_ctx)
14 TRPS_INSTANCE *trps=talloc(mem_ctx, TRPS_INSTANCE);
21 trps->mq=tr_mq_new(trps);
23 /* failed to allocate mq */
31 void trps_free (TRPS_INSTANCE *trps)
37 TR_MQ_MSG *trps_mq_pop(TRPS_INSTANCE *trps)
39 return tr_mq_pop(trps->mq);
42 void trps_mq_append(TRPS_INSTANCE *trps, TR_MQ_MSG *msg)
44 tr_mq_append(trps->mq, msg);
47 /* stand-in for a function that finds the connection for a particular peer */
49 static TRP_CONNECTION *trps_find_connection(TRPS_INSTANCE *trps)
55 void trps_add_connection(TRPS_INSTANCE *trps, TRP_CONNECTION *new)
60 trp_connection_append(trps->conn, new);
62 talloc_steal(trps, new);
65 /* ok to call more than once; guarantees connection no longer in the list.
66 * Caller is responsible for freeing the removed element afterwards. */
67 void trps_remove_connection(TRPS_INSTANCE *trps, TRP_CONNECTION *remove)
69 trps->conn=trp_connection_remove(trps->conn, remove);
72 void trps_add_trpc(TRPS_INSTANCE *trps, TRPC_INSTANCE *trpc)
77 trpc_append(trps->trpc, trpc);
79 talloc_steal(trps, trpc);
82 /* ok to call more than once; guarantees trpc no longer in the list.
83 * Caller is responsible for freeing the removed element afterwards. */
84 void trps_remove_trpc(TRPS_INSTANCE *trps, TRPC_INSTANCE *remove)
86 trps->trpc=trpc_remove(trps->trpc, remove);
89 TRP_RC trps_send_msg (TRPS_INSTANCE *trps, void *peer, const char *msg)
91 TALLOC_CTX *tmp_ctx=talloc_new(NULL);
92 TR_MQ_MSG *mq_msg=NULL;
96 /* Currently ignore peer and just send to an open connection.
97 * In reality, need to identify the correct peer and send via that
99 if (trps->trpc != NULL) {
100 if (trpc_get_status(trps->trpc)!=TRP_CONNECTION_UP)
101 tr_debug("trps_send_msg: skipping message sent while TRPC connection not up.");
103 mq_msg=tr_mq_msg_new(tmp_ctx, "trpc_send");
104 msg_dup=talloc_strdup(mq_msg, msg); /* get local copy in mq_msg context */
105 tr_mq_msg_set_payload(mq_msg, msg_dup, NULL); /* no need for a free() func */
106 trpc_mq_append(trps->trpc, mq_msg);
110 talloc_free(tmp_ctx);
114 static int trps_listen (TRPS_INSTANCE *trps, int port)
121 struct sockaddr_storage storage;
122 struct sockaddr_in in4;
125 struct sockaddr_in *saddr = (struct sockaddr_in *) &addr.in4;
127 saddr->sin_port = htons (port);
128 saddr->sin_family = AF_INET;
129 saddr->sin_addr.s_addr = INADDR_ANY;
131 if (0 > (conn = socket (AF_INET, SOCK_STREAM, 0)))
134 setsockopt(conn, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
136 if (0 > (rc = bind (conn, (struct sockaddr *) saddr, sizeof(struct sockaddr_in))))
139 if (0 > (rc = listen(conn, 512)))
142 tr_debug("trps_listen: TRP Server listening on port %d", port);
146 /* returns EACCES if authorization is denied */
147 int trps_auth_cb(gss_name_t clientName, gss_buffer_t displayName, void *data)
149 TRPS_INSTANCE *inst = (TRPS_INSTANCE *)data;
152 if (0!=inst->auth_handler(clientName, displayName, inst->cookie)) {
153 tr_debug("trps_auth_cb: client '%.*s' denied authorization.", displayName->length, displayName->value);
154 result=EACCES; /* denied */
160 static TRP_RC trps_read_message(TRPS_INSTANCE *trps, TRP_CONNECTION *conn, TR_MSG **msg)
166 tr_debug("trps_read_message: started");
167 if (err = gsscon_read_encrypted_token(trp_connection_get_fd(conn),
168 *(trp_connection_get_gssctx(conn)),
171 tr_debug("trps_read_message: error");
177 tr_debug("trps_read_message(): Request Received, %u bytes.", (unsigned) buflen);
178 tr_debug("trps_read_message(): %.*s", buflen, buf);
180 *msg=tr_msg_decode(buf, buflen);
185 /* fill in the next hop as the peer who just sent this to us */
186 trp_inforec_set_next_hop(*msg, trp_connection_get_peer(conn));
190 int trps_get_listener(TRPS_INSTANCE *trps,
191 TRPS_MSG_FUNC msg_handler,
192 TRP_AUTH_FUNC auth_handler,
193 const char *hostname,
199 if (0 > (listen = trps_listen(trps, port))) {
201 if (0 == strerror_r(errno, errbuf, 256)) {
202 tr_debug("trps_get_listener: Error opening port %d: %s.", port, errbuf);
204 tr_debug("trps_get_listener: Unknown error openining port %d.", port);
209 /* opening port succeeded */
210 tr_debug("trps_get_listener: Opened port %d.", port);
212 /* make this socket non-blocking */
213 if (0 != fcntl(listen, F_SETFL, O_NONBLOCK)) {
214 tr_debug("trps_get_listener: Error setting O_NONBLOCK.");
221 /* store the caller's request handler & cookie */
222 trps->msg_handler = msg_handler;
223 trps->auth_handler = auth_handler;
224 trps->hostname = talloc_strdup(trps, hostname);
226 trps->cookie = cookie;
232 void trps_handle_connection(TRPS_INSTANCE *trps, TRP_CONNECTION *conn)
234 TALLOC_CTX *tmp_ctx=talloc_new(NULL);
238 /* try to establish a GSS context */
239 if (0!=trp_connection_auth(conn, trps->auth_handler, trps->cookie)) {
240 tr_notice("tr_trps_conn_thread: failed to authorize connection");
243 tr_notice("trps_handle_connection: authorized connection");
245 /* loop as long as the connection exists */
246 while (trp_connection_get_status(conn)==TRP_CONNECTION_UP) {
247 rc=trps_read_message(trps, conn, &msg);
250 trps->msg_handler(trps, conn, msg); /* send the TR_MSG off to the callback */
254 trp_connection_close(conn);
258 tr_debug("trps_handle_connection: trps_read_message failed (%d)", rc);
262 tr_debug("trps_handle_connection: connection closed.");
263 talloc_free(tmp_ctx);