Navigation


source: freeDiameter/extensions/test_app/ta_cli.c @ 706:4ffbc9f1e922

Last change on this file since 706:4ffbc9f1e922 was 706:4ffbc9f1e922, checked in by Sebastien Decugis <sdecugis@nict.go.jp>, 11 years ago

Large UNTESTED commit with the following changes:

  • Improved DiameterIdentity? handling (esp. interationalization issues), and improve efficiency of some string operations in peers, sessions, and dictionary modules (closes #7)
  • Cleanup in the session module to free only unreferenced sessions (#16)
  • Removed fd_cpu_flush_cache(), replaced by more robust alternatives.
  • Improved peer state machine algorithm to counter SCTP multistream race condition.
File size: 8.6 KB
Line 
1/*********************************************************************************************************
2* Software License Agreement (BSD License)                                                               *
3* Author: Sebastien Decugis <sdecugis@nict.go.jp>                                                        *
4*                                                                                                        *
5* Copyright (c) 2011, WIDE Project and NICT                                                              *
6* All rights reserved.                                                                                   *
7*                                                                                                        *
8* Redistribution and use of this software in source and binary forms, with or without modification, are  *
9* permitted provided that the following conditions are met:                                              *
10*                                                                                                        *
11* * Redistributions of source code must retain the above                                                 *
12*   copyright notice, this list of conditions and the                                                    *
13*   following disclaimer.                                                                                *
14*                                                                                                        *
15* * Redistributions in binary form must reproduce the above                                              *
16*   copyright notice, this list of conditions and the                                                    *
17*   following disclaimer in the documentation and/or other                                               *
18*   materials provided with the distribution.                                                            *
19*                                                                                                        *
20* * Neither the name of the WIDE Project or NICT nor the                                                 *
21*   names of its contributors may be used to endorse or                                                  *
22*   promote products derived from this software without                                                  *
23*   specific prior written permission of WIDE Project and                                                *
24*   NICT.                                                                                                *
25*                                                                                                        *
26* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED *
27* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
28* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR *
29* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT     *
30* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS    *
31* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR *
32* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF   *
33* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                                                             *
34*********************************************************************************************************/
35
36/* Create and send a message, and receive it */
37
38/* Note that we use both sessions and the argument to answer callback to pass the same value.
39 * This is just for the purpose of checking everything went OK.
40 */
41
42#include "test_app.h"
43
44#include <stdio.h>
45
46static struct session_handler * ta_cli_reg = NULL;
47
48struct ta_mess_info {
49        int32_t         randval;        /* a random value to store in Test-AVP */
50        struct timespec ts;             /* Time of sending the message */
51} ;
52
53/* Cb called when an answer is received */
54static void ta_cb_ans(void * data, struct msg ** msg)
55{
56        struct ta_mess_info * mi = NULL;
57        struct timespec ts;
58        struct session * sess;
59        struct avp * avp;
60        struct avp_hdr * hdr;
61       
62        CHECK_SYS_DO( clock_gettime(CLOCK_REALTIME, &ts), return );
63
64        /* Search the session, retrieve its data */
65        {
66                int new;
67                CHECK_FCT_DO( fd_msg_sess_get(fd_g_config->cnf_dict, *msg, &sess, &new), return );
68                ASSERT( new == 0 );
69               
70                CHECK_FCT_DO( fd_sess_state_retrieve( ta_cli_reg, sess, &mi ), return );
71                TRACE_DEBUG( INFO, "%p %p", mi, data);
72                ASSERT( (void *)mi == data );
73        }
74       
75        /* Now log content of the answer */
76        fprintf(stderr, "RECV ");
77       
78        /* Value of Test-AVP */
79        CHECK_FCT_DO( fd_msg_search_avp ( *msg, ta_avp, &avp), return );
80        if (avp) {
81                CHECK_FCT_DO( fd_msg_avp_hdr( avp, &hdr ), return );
82                fprintf(stderr, "%x (%s) ", hdr->avp_value->i32, (hdr->avp_value->i32 == mi->randval) ? "Ok" : "PROBLEM");
83        } else {
84                fprintf(stderr, "no_Test-AVP ");
85        }
86       
87        /* Value of Result Code */
88        CHECK_FCT_DO( fd_msg_search_avp ( *msg, ta_res_code, &avp), return );
89        if (avp) {
90                CHECK_FCT_DO( fd_msg_avp_hdr( avp, &hdr ), return );
91                fprintf(stderr, "Status: %d ", hdr->avp_value->i32);
92        } else {
93                fprintf(stderr, "no_Result-Code ");
94        }
95       
96        /* Value of Origin-Host */
97        CHECK_FCT_DO( fd_msg_search_avp ( *msg, ta_origin_host, &avp), return );
98        if (avp) {
99                CHECK_FCT_DO( fd_msg_avp_hdr( avp, &hdr ), return );
100                fprintf(stderr, "From '%.*s' ", (int)hdr->avp_value->os.len, hdr->avp_value->os.data);
101        } else {
102                fprintf(stderr, "no_Origin-Host ");
103        }
104       
105        /* Value of Origin-Realm */
106        CHECK_FCT_DO( fd_msg_search_avp ( *msg, ta_origin_realm, &avp), return );
107        if (avp) {
108                CHECK_FCT_DO( fd_msg_avp_hdr( avp, &hdr ), return );
109                fprintf(stderr, "('%.*s') ", (int)hdr->avp_value->os.len, hdr->avp_value->os.data);
110        } else {
111                fprintf(stderr, "no_Origin-Realm ");
112        }
113       
114        /* Now compute how long it took */
115        if (ts.tv_nsec > mi->ts.tv_nsec) {
116                fprintf(stderr, "in %d.%06ld sec", 
117                                (int)(ts.tv_sec - mi->ts.tv_sec),
118                                (long)(ts.tv_nsec - mi->ts.tv_nsec) / 1000);
119        } else {
120                fprintf(stderr, "in %d.%06ld sec", 
121                                (int)(ts.tv_sec + 1 - mi->ts.tv_sec),
122                                (long)(1000000000 + ts.tv_nsec - mi->ts.tv_nsec) / 1000);
123        }
124       
125        fprintf(stderr, "\n");
126        fflush(stderr);
127       
128        /* Free the message */
129        CHECK_FCT_DO(fd_msg_free(*msg), return);
130        *msg = NULL;
131       
132        free(mi);
133       
134        return;
135}
136
137/* Create a test message */
138static void ta_cli_test_message()
139{
140        struct msg * req = NULL;
141        struct avp * avp;
142        union avp_value val;
143        struct ta_mess_info * mi = NULL, *svg;
144        struct session *sess = NULL;
145       
146        TRACE_DEBUG(FULL, "Creating a new message for sending.");
147       
148        /* Create the request from template */
149        CHECK_FCT_DO( fd_msg_new( ta_cmd_r, MSGFL_ALLOC_ETEID, &req ), goto out );
150       
151        /* Create a new session */
152        #define TEST_APP_SID_OPT  "app_test"
153        CHECK_FCT_DO( fd_sess_new( &sess, fd_g_config->cnf_diamid, fd_g_config->cnf_diamid_len, (os0_t)TEST_APP_SID_OPT, CONSTSTRLEN(TEST_APP_SID_OPT) ), goto out );
154       
155        /* Create the random value to store with the session */
156        mi = malloc(sizeof(struct ta_mess_info));
157        if (mi == NULL) {
158                fd_log_debug("malloc failed: %s", strerror(errno));
159                goto out;
160        }
161       
162        mi->randval = (int32_t)random();
163       
164        /* Now set all AVPs values */
165       
166        /* Session-Id */
167        {
168                os0_t sid;
169                size_t sidlen;
170                CHECK_FCT_DO( fd_sess_getsid ( sess, &sid, &sidlen ), goto out );
171                CHECK_FCT_DO( fd_msg_avp_new ( ta_sess_id, 0, &avp ), goto out );
172                val.os.data = sid;
173                val.os.len  = sidlen;
174                CHECK_FCT_DO( fd_msg_avp_setvalue( avp, &val ), goto out );
175                CHECK_FCT_DO( fd_msg_avp_add( req, MSG_BRW_FIRST_CHILD, avp ), goto out );
176               
177        }
178       
179        /* Set the Destination-Realm AVP */
180        {
181                CHECK_FCT_DO( fd_msg_avp_new ( ta_dest_realm, 0, &avp ), goto out  );
182                val.os.data = (unsigned char *)(ta_conf->dest_realm);
183                val.os.len  = strlen(ta_conf->dest_realm);
184                CHECK_FCT_DO( fd_msg_avp_setvalue( avp, &val ), goto out  );
185                CHECK_FCT_DO( fd_msg_avp_add( req, MSG_BRW_LAST_CHILD, avp ), goto out  );
186        }
187       
188        /* Set the Destination-Host AVP if needed*/
189        if (ta_conf->dest_host) {
190                CHECK_FCT_DO( fd_msg_avp_new ( ta_dest_host, 0, &avp ), goto out  );
191                val.os.data = (unsigned char *)(ta_conf->dest_host);
192                val.os.len  = strlen(ta_conf->dest_host);
193                CHECK_FCT_DO( fd_msg_avp_setvalue( avp, &val ), goto out  );
194                CHECK_FCT_DO( fd_msg_avp_add( req, MSG_BRW_LAST_CHILD, avp ), goto out  );
195        }
196       
197        /* Set Origin-Host & Origin-Realm */
198        CHECK_FCT_DO( fd_msg_add_origin ( req, 0 ), goto out  );
199       
200        /* Set the User-Name AVP if needed*/
201        if (ta_conf->user_name) {
202                CHECK_FCT_DO( fd_msg_avp_new ( ta_user_name, 0, &avp ), goto out  );
203                val.os.data = (unsigned char *)(ta_conf->user_name);
204                val.os.len  = strlen(ta_conf->user_name);
205                CHECK_FCT_DO( fd_msg_avp_setvalue( avp, &val ), goto out  );
206                CHECK_FCT_DO( fd_msg_avp_add( req, MSG_BRW_LAST_CHILD, avp ), goto out  );
207        }
208       
209        /* Set the Test-AVP AVP */
210        {
211                CHECK_FCT_DO( fd_msg_avp_new ( ta_avp, 0, &avp ), goto out  );
212                val.i32 = mi->randval;
213                CHECK_FCT_DO( fd_msg_avp_setvalue( avp, &val ), goto out  );
214                CHECK_FCT_DO( fd_msg_avp_add( req, MSG_BRW_LAST_CHILD, avp ), goto out  );
215        }
216       
217        CHECK_SYS_DO( clock_gettime(CLOCK_REALTIME, &mi->ts), goto out );
218       
219        /* Keep a pointer to the session data for debug purpose, in real life we would not need it */
220        svg = mi;
221       
222        /* Store this value in the session */
223        CHECK_FCT_DO( fd_sess_state_store ( ta_cli_reg, sess, &mi ), goto out ); 
224       
225        /* Log sending the message */
226        fprintf(stderr, "SEND %x to '%s' (%s)\n", svg->randval, ta_conf->dest_realm, ta_conf->dest_host?:"-" );
227        fflush(stderr);
228       
229        /* Send the request */
230        CHECK_FCT_DO( fd_msg_send( &req, ta_cb_ans, svg ), goto out );
231
232out:
233        return;
234}
235
236int ta_cli_init(void)
237{
238        CHECK_FCT( fd_sess_handler_create(&ta_cli_reg, free, NULL) );
239       
240        CHECK_FCT( fd_event_trig_regcb(ta_conf->signal, "test_app.cli", ta_cli_test_message ) );
241       
242        return 0;
243}
244
245void ta_cli_fini(void)
246{
247        // CHECK_FCT_DO( fd_sig_unregister(ta_conf->signal), /* continue */ );
248       
249        CHECK_FCT_DO( fd_sess_handler_destroy(&ta_cli_reg, NULL), /* continue */ );
250       
251        return;
252};
Note: See TracBrowser for help on using the repository browser.