| 1 | #include "config.h" | 
|---|
| 2 | #include <stdio.h> | 
|---|
| 3 | #include <stdlib.h> | 
|---|
| 4 | #include <string.h> | 
|---|
| 5 |  | 
|---|
| 6 | #include <orbit/orbit.h> | 
|---|
| 7 | #include <orbit/poa/orbit-adaptor.h> | 
|---|
| 8 | #include "GIOP/giop-debug.h" | 
|---|
| 9 |  | 
|---|
| 10 | #include "test-giop-frag.h" | 
|---|
| 11 |  | 
|---|
| 12 | #ifndef G_ENABLE_DEBUG | 
|---|
| 13 | #ifdef __GNUC__ | 
|---|
| 14 | #  warning GIOP test hooks only enabled in a debugging build | 
|---|
| 15 | #endif | 
|---|
| 16 | int | 
|---|
| 17 | main (int argc, char *argv[]) | 
|---|
| 18 | { | 
|---|
| 19 | g_warning ("GIOP test hooks only enabled in a debugging build"); | 
|---|
| 20 | return 0; | 
|---|
| 21 | } | 
|---|
| 22 | #else | 
|---|
| 23 |  | 
|---|
| 24 | static LinkWriteOpts  *non_blocking = NULL; | 
|---|
| 25 | static GIOPServer     *server     = NULL; | 
|---|
| 26 | static GIOPConnection *server_cnx = NULL; | 
|---|
| 27 | static GIOPConnection *cnx        = NULL; | 
|---|
| 28 |  | 
|---|
| 29 | static gboolean fragment_done; | 
|---|
| 30 |  | 
|---|
| 31 | static void | 
|---|
| 32 | wait_for_disconnect (void) | 
|---|
| 33 | { | 
|---|
| 34 | int i; | 
|---|
| 35 |  | 
|---|
| 36 | /* a main_pending just looks for IO and not HUPs */ | 
|---|
| 37 | for (i = 0; i < 10; i++) { | 
|---|
| 38 | if (link_main_pending ()) | 
|---|
| 39 | i = 0; | 
|---|
| 40 | link_main_iteration (FALSE); | 
|---|
| 41 | } | 
|---|
| 42 | } | 
|---|
| 43 |  | 
|---|
| 44 | static void | 
|---|
| 45 | hook_unexpected_frag_reply (GIOPRecvBuffer *buf) | 
|---|
| 46 | { | 
|---|
| 47 | char *p; | 
|---|
| 48 | const char testa[] = "ADVENTURE";  /* cf. Willard Price */ | 
|---|
| 49 | const char testb[] = "MILLENNIUM"; /* cf. Robbie Williams */ | 
|---|
| 50 | const char testc[] = "It isn't,  said the Caterpillar"; | 
|---|
| 51 | const char testd[] = "Why?  said the Caterpillar"; | 
|---|
| 52 |  | 
|---|
| 53 | fragment_done = TRUE; | 
|---|
| 54 |  | 
|---|
| 55 | g_assert (buf != NULL); | 
|---|
| 56 | g_assert (buf->left_to_read == 0); | 
|---|
| 57 | g_assert (buf->msg.header.message_size == 1727); | 
|---|
| 58 |  | 
|---|
| 59 | p = buf->message_body + 52; | 
|---|
| 60 | g_assert (!strncmp (p, testa, sizeof (testa) - 1)); | 
|---|
| 61 |  | 
|---|
| 62 | p = buf->message_body + 97; | 
|---|
| 63 | g_assert (!strncmp (p, testb, sizeof (testb) - 1)); | 
|---|
| 64 |  | 
|---|
| 65 | p = buf->message_body + 1002; | 
|---|
| 66 | g_assert (!strncmp (p, testc, sizeof (testc) - 1)); | 
|---|
| 67 |  | 
|---|
| 68 | p = buf->message_body + 1702; | 
|---|
| 69 | g_assert (!strncmp (p, testd, sizeof (testd) - 1)); | 
|---|
| 70 | } | 
|---|
| 71 |  | 
|---|
| 72 | static void | 
|---|
| 73 | test_fragments (void) | 
|---|
| 74 | { | 
|---|
| 75 | link_connection_write ( | 
|---|
| 76 | LINK_CONNECTION (cnx), | 
|---|
| 77 | giop_fragment_data, | 
|---|
| 78 | sizeof (giop_fragment_data), | 
|---|
| 79 | non_blocking); | 
|---|
| 80 |  | 
|---|
| 81 | giop_debug_hook_unexpected_reply = hook_unexpected_frag_reply; | 
|---|
| 82 |  | 
|---|
| 83 | fragment_done = FALSE; | 
|---|
| 84 | while (!fragment_done) | 
|---|
| 85 | link_main_iteration (FALSE); | 
|---|
| 86 |  | 
|---|
| 87 | giop_debug_hook_unexpected_reply = NULL; | 
|---|
| 88 | } | 
|---|
| 89 |  | 
|---|
| 90 | static gboolean spoof_done; | 
|---|
| 91 | static gboolean spoof_succeeded; | 
|---|
| 92 |  | 
|---|
| 93 | static void | 
|---|
| 94 | test_spoof_callback (GIOPMessageQueueEntry *ent) | 
|---|
| 95 | { | 
|---|
| 96 | spoof_done = spoof_succeeded = TRUE; | 
|---|
| 97 | } | 
|---|
| 98 |  | 
|---|
| 99 | static void | 
|---|
| 100 | test_spoof_hook (GIOPRecvBuffer *buffer, | 
|---|
| 101 | GIOPMessageQueueEntry *ent) | 
|---|
| 102 | { | 
|---|
| 103 | spoof_done = TRUE; | 
|---|
| 104 | } | 
|---|
| 105 |  | 
|---|
| 106 | static void | 
|---|
| 107 | test_spoofing (void) | 
|---|
| 108 | { | 
|---|
| 109 | int i; | 
|---|
| 110 | GIOPConnection *misc; | 
|---|
| 111 | GIOPSendBuffer *reply; | 
|---|
| 112 | GIOPMessageQueueEntry ent; | 
|---|
| 113 | CORBA_unsigned_long request_id; | 
|---|
| 114 |  | 
|---|
| 115 | request_id = 0x12345; | 
|---|
| 116 | giop_debug_hook_spoofed_reply = test_spoof_hook; | 
|---|
| 117 | misc = g_object_new (giop_connection_get_type (), NULL); | 
|---|
| 118 |  | 
|---|
| 119 | for (i = 0; i < 2; i++) { | 
|---|
| 120 | giop_recv_list_setup_queue_entry (&ent, !i ? server_cnx : misc, | 
|---|
| 121 | GIOP_REPLY, request_id); | 
|---|
| 122 | giop_recv_list_setup_queue_entry_async (&ent, test_spoof_callback); | 
|---|
| 123 |  | 
|---|
| 124 | reply = giop_send_buffer_use_reply ( | 
|---|
| 125 | GIOP_1_2, request_id , CORBA_NO_EXCEPTION); | 
|---|
| 126 |  | 
|---|
| 127 | spoof_done = FALSE; | 
|---|
| 128 | spoof_succeeded = FALSE; | 
|---|
| 129 |  | 
|---|
| 130 | g_assert (!giop_send_buffer_write (reply, cnx, TRUE)); | 
|---|
| 131 |  | 
|---|
| 132 | giop_send_buffer_unuse (reply); | 
|---|
| 133 |  | 
|---|
| 134 | while (!spoof_done) | 
|---|
| 135 | link_main_iteration (TRUE); | 
|---|
| 136 |  | 
|---|
| 137 | switch (i) { | 
|---|
| 138 | case 0: /* valid */ | 
|---|
| 139 | g_assert (spoof_succeeded); | 
|---|
| 140 | break; | 
|---|
| 141 | case 1: /* invalid */ | 
|---|
| 142 | g_assert (!spoof_succeeded); | 
|---|
| 143 | link_connection_ref (cnx); | 
|---|
| 144 | wait_for_disconnect (); | 
|---|
| 145 | g_assert (LINK_CONNECTION (cnx)->status == LINK_DISCONNECTED); | 
|---|
| 146 | link_connection_unref (cnx); | 
|---|
| 147 | break; | 
|---|
| 148 | default: | 
|---|
| 149 | g_assert_not_reached (); | 
|---|
| 150 | break; | 
|---|
| 151 | } | 
|---|
| 152 | } | 
|---|
| 153 | link_connection_unref (misc); | 
|---|
| 154 | giop_debug_hook_spoofed_reply = NULL; | 
|---|
| 155 | } | 
|---|
| 156 |  | 
|---|
| 157 | static void | 
|---|
| 158 | run_test_hook_new_connection (GIOPServer     *server, | 
|---|
| 159 | GIOPConnection *new_cnx) | 
|---|
| 160 | { | 
|---|
| 161 | g_assert (g_type_is_a (G_TYPE_FROM_INSTANCE (server), | 
|---|
| 162 | GIOP_TYPE_SERVER)); | 
|---|
| 163 | g_assert (g_type_is_a (G_TYPE_FROM_INSTANCE (new_cnx), | 
|---|
| 164 | GIOP_TYPE_CONNECTION)); | 
|---|
| 165 |  | 
|---|
| 166 | server_cnx = new_cnx; | 
|---|
| 167 | } | 
|---|
| 168 |  | 
|---|
| 169 | static void | 
|---|
| 170 | run_test (CORBA_ORB orb, void (*do_test) (void), gboolean reverse) | 
|---|
| 171 | { | 
|---|
| 172 | #ifndef G_OS_WIN32 | 
|---|
| 173 | server = giop_server_new (GIOP_1_2, "UNIX", NULL, NULL, 0, orb); | 
|---|
| 174 | #else | 
|---|
| 175 | server = giop_server_new (GIOP_1_2, "IPv4", NULL, NULL, 0, orb); | 
|---|
| 176 | #endif | 
|---|
| 177 | server_cnx = NULL; | 
|---|
| 178 | g_assert (LINK_IS_SERVER (server)); | 
|---|
| 179 |  | 
|---|
| 180 | giop_debug_hook_new_connection = run_test_hook_new_connection; | 
|---|
| 181 |  | 
|---|
| 182 | #ifndef G_OS_WIN32 | 
|---|
| 183 | cnx = giop_connection_initiate ( | 
|---|
| 184 | orb, "UNIX", | 
|---|
| 185 | LINK_SERVER (server)->local_host_info, | 
|---|
| 186 | LINK_SERVER (server)->local_serv_info, | 
|---|
| 187 | LINK_CONNECTION_NONBLOCKING, | 
|---|
| 188 | GIOP_1_2); | 
|---|
| 189 | #else | 
|---|
| 190 | cnx = giop_connection_initiate ( | 
|---|
| 191 | orb, "IPv4", | 
|---|
| 192 | LINK_SERVER (server)->local_host_info, | 
|---|
| 193 | LINK_SERVER (server)->local_serv_info, | 
|---|
| 194 | LINK_CONNECTION_NONBLOCKING, | 
|---|
| 195 | GIOP_1_2); | 
|---|
| 196 | #endif | 
|---|
| 197 | g_assert (cnx != NULL); | 
|---|
| 198 |  | 
|---|
| 199 | while (server_cnx == NULL) | 
|---|
| 200 | link_main_iteration (TRUE); | 
|---|
| 201 |  | 
|---|
| 202 | giop_debug_hook_new_connection = NULL; | 
|---|
| 203 | g_assert (server_cnx != NULL); | 
|---|
| 204 |  | 
|---|
| 205 | if (reverse) { | 
|---|
| 206 | gpointer tmp = server_cnx; | 
|---|
| 207 | server_cnx = cnx; | 
|---|
| 208 | cnx = tmp; | 
|---|
| 209 | } | 
|---|
| 210 |  | 
|---|
| 211 | do_test (); | 
|---|
| 212 |  | 
|---|
| 213 | if (reverse) { | 
|---|
| 214 | gpointer tmp = server_cnx; | 
|---|
| 215 | server_cnx = cnx; | 
|---|
| 216 | cnx = tmp; | 
|---|
| 217 | } | 
|---|
| 218 |  | 
|---|
| 219 | g_object_unref (server); | 
|---|
| 220 | server_cnx = NULL; | 
|---|
| 221 | server = NULL; | 
|---|
| 222 | link_connection_unref (cnx); | 
|---|
| 223 | cnx = NULL; | 
|---|
| 224 | } | 
|---|
| 225 |  | 
|---|
| 226 | static void | 
|---|
| 227 | test_cookie (CORBA_ORB orb) | 
|---|
| 228 | { | 
|---|
| 229 | int i; | 
|---|
| 230 | ORBit_ObjectAdaptor adaptor; | 
|---|
| 231 | CORBA_sequence_CORBA_octet *seq; | 
|---|
| 232 |  | 
|---|
| 233 | adaptor = g_ptr_array_index (orb->adaptors, 0); | 
|---|
| 234 | g_assert (adaptor != NULL); | 
|---|
| 235 |  | 
|---|
| 236 | seq = &adaptor->adaptor_key; | 
|---|
| 237 |  | 
|---|
| 238 | g_assert (seq->_length > 8); | 
|---|
| 239 |  | 
|---|
| 240 | fprintf (stderr, "ORB cookie (%ld): ", | 
|---|
| 241 | (long) seq->_length); | 
|---|
| 242 |  | 
|---|
| 243 | for (i = 0; i < seq->_length; i++) | 
|---|
| 244 | fprintf (stderr, "%.2x", seq->_buffer [i]); | 
|---|
| 245 |  | 
|---|
| 246 | fprintf (stderr, " - looks random ?\n"); | 
|---|
| 247 | } | 
|---|
| 248 |  | 
|---|
| 249 | #define MANGLE_ITERATIONS 1000 | 
|---|
| 250 |  | 
|---|
| 251 | /* fraction denominators */ | 
|---|
| 252 | #define MANGLE_HEADER 8 | 
|---|
| 253 | #define MANGLE_BODY   64 | 
|---|
| 254 |  | 
|---|
| 255 | static int bits_corrupted = 0; | 
|---|
| 256 | static int cnx_closed = 0; | 
|---|
| 257 |  | 
|---|
| 258 | static void | 
|---|
| 259 | test_incoming_mangler (GIOPRecvBuffer *buf) | 
|---|
| 260 | { | 
|---|
| 261 | int r; | 
|---|
| 262 | guchar *start, *p; | 
|---|
| 263 | CORBA_long len; | 
|---|
| 264 |  | 
|---|
| 265 | switch (buf->state) { | 
|---|
| 266 | case GIOP_MSG_READING_HEADER: | 
|---|
| 267 | start = (guchar *) &buf->msg.header; | 
|---|
| 268 | r = MANGLE_HEADER; | 
|---|
| 269 | break; | 
|---|
| 270 | case GIOP_MSG_READING_BODY: | 
|---|
| 271 | start = (guchar *) buf->message_body + 12; | 
|---|
| 272 | r = MANGLE_BODY; | 
|---|
| 273 | break; | 
|---|
| 274 | default: | 
|---|
| 275 | start = NULL; | 
|---|
| 276 | r = 0; | 
|---|
| 277 | g_error ("Odd msg status"); | 
|---|
| 278 | break; | 
|---|
| 279 | } | 
|---|
| 280 |  | 
|---|
| 281 | len = buf->end - start; | 
|---|
| 282 |  | 
|---|
| 283 | for (p = start; p < buf->end; p++) { | 
|---|
| 284 | int i = rand (); | 
|---|
| 285 |  | 
|---|
| 286 | if ((i * 1.0 * r) / (RAND_MAX + 1.0) <= 1.0) { | 
|---|
| 287 | int bit = 1 << ((i >> 8) & 0x7); | 
|---|
| 288 | p--; /* can do the same again */ | 
|---|
| 289 | *p ^= bit; | 
|---|
| 290 | bits_corrupted++; | 
|---|
| 291 | } | 
|---|
| 292 | } | 
|---|
| 293 | } | 
|---|
| 294 |  | 
|---|
| 295 | static void | 
|---|
| 296 | test_mangling_exec (void) | 
|---|
| 297 | { | 
|---|
| 298 | link_connection_write ( | 
|---|
| 299 | LINK_CONNECTION (cnx), | 
|---|
| 300 | giop_fragment_data, | 
|---|
| 301 | sizeof (giop_fragment_data), | 
|---|
| 302 | non_blocking); | 
|---|
| 303 |  | 
|---|
| 304 | wait_for_disconnect (); /* Wait around for things to blow up */ | 
|---|
| 305 |  | 
|---|
| 306 | if (cnx->parent.status == LINK_DISCONNECTED) | 
|---|
| 307 | cnx_closed++; | 
|---|
| 308 | } | 
|---|
| 309 |  | 
|---|
| 310 | static void | 
|---|
| 311 | test_mangling (CORBA_ORB orb) | 
|---|
| 312 | { | 
|---|
| 313 | int i; | 
|---|
| 314 |  | 
|---|
| 315 | giop_debug_hook_incoming_mangler = test_incoming_mangler; | 
|---|
| 316 |  | 
|---|
| 317 | fprintf (stderr, "Testing data corruption ...\n"); | 
|---|
| 318 | for (i = 0; i < MANGLE_ITERATIONS; i++) { | 
|---|
| 319 | run_test (orb, test_mangling_exec, i % 1); | 
|---|
| 320 | } | 
|---|
| 321 |  | 
|---|
| 322 | fprintf (stderr, " %d bits corrupted, %d cnx terminated\n", | 
|---|
| 323 | bits_corrupted, cnx_closed); | 
|---|
| 324 |  | 
|---|
| 325 | giop_debug_hook_incoming_mangler = NULL; | 
|---|
| 326 | } | 
|---|
| 327 |  | 
|---|
| 328 | int | 
|---|
| 329 | main (int argc, char *argv[]) | 
|---|
| 330 | { | 
|---|
| 331 | CORBA_ORB orb; | 
|---|
| 332 | CORBA_Environment ev; | 
|---|
| 333 |  | 
|---|
| 334 | CORBA_exception_init (&ev); | 
|---|
| 335 |  | 
|---|
| 336 | orb = CORBA_ORB_init (&argc, argv, "orbit-local-orb", &ev); | 
|---|
| 337 | g_assert (ev._major == CORBA_NO_EXCEPTION); | 
|---|
| 338 | non_blocking = link_write_options_new (FALSE); | 
|---|
| 339 |  | 
|---|
| 340 | fprintf (stderr, "Testing fragment support ...\n"); | 
|---|
| 341 | run_test (orb, test_fragments, FALSE); | 
|---|
| 342 | run_test (orb, test_fragments, TRUE); | 
|---|
| 343 |  | 
|---|
| 344 | fprintf (stderr, "Testing spoofing ...\n"); | 
|---|
| 345 | run_test (orb, test_spoofing, FALSE); | 
|---|
| 346 | run_test (orb, test_spoofing, TRUE); | 
|---|
| 347 |  | 
|---|
| 348 | test_cookie (orb); | 
|---|
| 349 | test_mangling (orb); | 
|---|
| 350 |  | 
|---|
| 351 | link_write_options_free (non_blocking); | 
|---|
| 352 | CORBA_ORB_destroy (orb, &ev); | 
|---|
| 353 | g_assert (ev._major == CORBA_NO_EXCEPTION); | 
|---|
| 354 | CORBA_Object_release ((CORBA_Object) orb, &ev); | 
|---|
| 355 | g_assert (ev._major == CORBA_NO_EXCEPTION); | 
|---|
| 356 |  | 
|---|
| 357 | fprintf (stderr, "All tests passed.\n"); | 
|---|
| 358 |  | 
|---|
| 359 | return 0; | 
|---|
| 360 | } | 
|---|
| 361 |  | 
|---|
| 362 | #endif /* G_ENABLE_DEBUG */ | 
|---|