4e02feae6451d457c597d62b1aa1c3bb0566888b
[trust_router.git] / trp / trpc.c
1 #include <fcntl.h>
2 #include <talloc.h>
3 #include <errno.h>
4 #include <unistd.h>
5
6 #include <gsscon.h>
7 #include <tr_rp.h>
8 #include <tr_debug.h>
9 #include <trp_internal.h>
10
11 static int trpc_destructor(void *object)
12 {
13   TRPC_INSTANCE *trpc=talloc_get_type_abort(object, TRPC_INSTANCE);
14   if (trpc->gssname!=NULL)
15     tr_free_name(trpc->gssname);
16   return 0;
17 }
18
19 /* also allocates the incoming mq */
20 TRPC_INSTANCE *trpc_new (TALLOC_CTX *mem_ctx)
21 {
22   TRPC_INSTANCE *trpc=talloc(mem_ctx, TRPC_INSTANCE);
23   if (trpc!=NULL) {
24     trpc->next=NULL;
25     trpc->server=NULL;
26     trpc->port=0;
27     trpc->conn=NULL;
28     trpc->mq=tr_mq_new(trpc);
29     if (trpc->mq==NULL) {
30       talloc_free(trpc);
31       trpc=NULL;
32     } else
33       talloc_set_destructor((void *)trpc, trpc_destructor);
34     
35   }
36   return trpc;
37 }
38
39 void trpc_free (TRPC_INSTANCE *trpc)
40 {
41   if (trpc)
42     talloc_free(trpc);
43 }
44
45 TRPC_INSTANCE *trpc_get_next(TRPC_INSTANCE *trpc)
46 {
47   return trpc->next;
48 }
49
50 void trpc_set_next(TRPC_INSTANCE *trpc, TRPC_INSTANCE *next)
51 {
52   trpc->next=next;
53 }
54
55 /* Ok to call more than once; guarantees trpc no longer in the list. Does not free removed element.
56  * Returns handle to new list, you must replace your old handle on the list with this.  */
57 TRPC_INSTANCE *trpc_remove(TRPC_INSTANCE *trpc, TRPC_INSTANCE *remove)
58 {
59   TRPC_INSTANCE *cur=trpc;
60   TRPC_INSTANCE *last=NULL;
61
62   if (cur==NULL)
63     return NULL;
64
65   /* first element is a special case */
66   if (cur==remove) {
67     trpc=trpc_get_next(cur); /* advance list head */
68   } else {
69     /* it was not the first element */
70     last=cur;
71     cur=trpc_get_next(cur);
72     while (cur!=NULL) {
73       if (cur==remove) {
74         trpc_set_next(last, trpc_get_next(cur));
75         break;
76       }
77       last=cur;
78       cur=trpc_get_next(cur);
79     }
80   }
81   return trpc;
82 }
83
84 static TRPC_INSTANCE *trpc_get_tail(TRPC_INSTANCE *trpc)
85 {
86   while((trpc!=NULL)&&(trpc_get_next(trpc)!=NULL))
87     trpc=trpc_get_next(trpc);
88   return trpc;
89 }
90
91 void trpc_append(TRPC_INSTANCE *trpc, TRPC_INSTANCE *new)
92 {
93   trpc_set_next(trpc_get_tail(trpc), new);
94 }
95
96 char *trpc_get_server(TRPC_INSTANCE *trpc)
97 {
98   return trpc->server;
99 }
100
101 void trpc_set_server(TRPC_INSTANCE *trpc, char *server)
102 {
103   trpc->server=server;
104 }
105
106 TR_NAME *trpc_get_gssname(TRPC_INSTANCE *trpc)
107 {
108   return trpc->gssname;
109 }
110
111 /* takes responsibility for freeing gssname */
112 void trpc_set_gssname(TRPC_INSTANCE *trpc, TR_NAME *gssname)
113 {
114   trpc->gssname=gssname;
115 }
116
117 unsigned int trpc_get_port(TRPC_INSTANCE *trpc)
118 {
119   return trpc->port;
120 }
121
122 void trpc_set_port(TRPC_INSTANCE *trpc, unsigned int port)
123 {
124   trpc->port=port;
125 }
126
127 TRP_CONNECTION *trpc_get_conn(TRPC_INSTANCE *trpc)
128 {
129   return trpc->conn;
130 }
131
132 void trpc_set_conn(TRPC_INSTANCE *trpc, TRP_CONNECTION *conn)
133 {
134   trpc->conn=conn;
135 }
136
137 TRP_CONNECTION_STATUS trpc_get_status(TRPC_INSTANCE *trpc)
138 {
139   return trp_connection_get_status(trpc_get_conn(trpc));
140 }
141
142 TR_MQ *trpc_get_mq(TRPC_INSTANCE *trpc)
143 {
144   return trpc->mq;
145 }
146
147 void trpc_set_mq(TRPC_INSTANCE *trpc, TR_MQ *mq)
148 {
149   trpc->mq=mq;
150 }
151
152 /* submit msg to trpc for transmission */
153 void trpc_mq_add(TRPC_INSTANCE *trpc, TR_MQ_MSG *msg)
154 {
155   tr_mq_add(trpc->mq, msg);
156 }
157
158 TR_MQ_MSG *trpc_mq_pop(TRPC_INSTANCE *trpc)
159 {
160   return tr_mq_pop(trpc->mq);
161 }
162
163 void trpc_mq_clear(TRPC_INSTANCE *trpc)
164 {
165   tr_mq_clear(trpc->mq);
166 }
167
168 TRP_RC trpc_connect(TRPC_INSTANCE *trpc)
169 {
170   return trp_connection_initiate(trpc_get_conn(trpc), trpc_get_server(trpc), trpc_get_port(trpc));
171 }
172
173 /* simple function, based on tidc_send_req */
174 TRP_RC trpc_send_msg (TRPC_INSTANCE *trpc, 
175                       const char *msg_content)
176 {
177   int err=0;
178   TRP_RC rc=TRP_SUCCESS;
179
180   /* Send the request over the connection */
181   if (err = gsscon_write_encrypted_token(trp_connection_get_fd(trpc_get_conn(trpc)),
182                                          *trp_connection_get_gssctx(trpc_get_conn(trpc)),
183                                          msg_content, 
184                                          strlen(msg_content))) {
185     tr_err( "trpc_send_msg: Error sending message over connection.\n");
186     rc=TRP_ERROR;
187   }
188   return rc;
189 }