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