| 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 */
|
|---|