ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/socket/lowlevel.C
(Generate patch)

Comparing deliantra/server/socket/lowlevel.C (file contents):
Revision 1.89 by root, Tue Nov 6 21:50:36 2012 UTC vs.
Revision 1.90 by root, Thu Nov 8 02:28:21 2012 UTC

48 * 48 *
49 * When the socket is clear to write, and we have backlogged data, this 49 * When the socket is clear to write, and we have backlogged data, this
50 * is called to write it out. 50 * is called to write it out.
51 */ 51 */
52 52
53 // write a nop to the socket at least every IDLE_NOP seconds. 53 // write a nop to the socket at least every IDLE_PING seconds.
54 if (!outputbuffer.len) 54 if (!outputbuffer.len)
55 { 55 {
56 if (last_send + IDLE_PING <= NOW && pl && pl->active) 56 if (last_send + IDLE_PING <= NOW && pl && pl->active)
57 { 57 {
58 // this is a bit ugly, but map1a seems to be the only 58 // this is a bit ugly, but map1a seems to be the only
343 socket_ev.poll (socket_ev.poll () & ~EV_WRITE); 343 socket_ev.poll (socket_ev.poll () & ~EV_WRITE);
344 } 344 }
345 345
346 if (revents & EV_READ) 346 if (revents & EV_READ)
347 { 347 {
348 //TODO: rate-limit tcp connection in better ways, important 348 int amount;
349 uint8 *rbuf;
349 350
351 if (ws_version)
352 {
353 if (ws_inbuf_len + 2048 > ws_inbuf_alloc)
354 ws_inbuf = (uint8 *)realloc (ws_inbuf, ws_inbuf_alloc += 4096);
355
356 rbuf = ws_inbuf;
357 amount = ws_inbuf_alloc - ws_inbuf_len;
358 }
359 else
360 {
361 rbuf = inbuf;
350 int amount = sizeof (inbuf) - inbuf_len; 362 amount = sizeof (inbuf) - inbuf_len;
363 }
351 364
352 if (!amount) 365 if (!amount)
353 { 366 {
354 // input buffer full 367 // input buffer full
355 LOG (llevError, "input buffer overflow."); 368 LOG (llevError, "input buffer overflow.");
356 destroy (); 369 destroy ();
357 return; 370 return;
358 } 371 }
359 372
373 amount = read (fd, ws_inbuf + ws_inbuf_len, amount);
374
375 if (!amount)
376 {
377 destroy ();
378 return;
379 }
380 else if (amount < 0)
381 {
382 if (errno != EAGAIN && errno != EINTR)
383 {
384 LOG (llevError, "read error: %s\n", strerror (errno));
385 destroy ();
386 return;
387 }
388
389 // should not be here, normally
390 }
391
360 if (ws_version) 392 if (ws_version)
361 { 393 {
362 if (ws_inbuf_len + 2048 > ws_inbuf_alloc) 394 ws_inbuf_len += amount;
363 ws_inbuf = (uint8 *)realloc (ws_inbuf, ws_inbuf_alloc += 4096);
364 395
365 int len = read (fd, ws_inbuf + ws_inbuf_len, ws_inbuf_alloc - ws_inbuf_len); 396 while (ws_inbuf_len)
366
367 if (len > 0)
368 { 397 {
369 ws_inbuf_len += len;
370
371 if (ws_inbuf_len < 2 + 4) // 6 is minimum length: op, len, mask 398 if (ws_inbuf_len < 2 + 4) // 6 is minimum length: op, len, mask
372 return; 399 break;
373 400
374 int d = 2; 401 int d = 2;
402 int fin = ws_inbuf [0] & 0x80;
375 int o = ws_inbuf [0] & 15; 403 int op = ws_inbuf [0] & 0x0f;
376 int l = ws_inbuf [1] & 127; 404 int len = ws_inbuf [1] & 0x7f;
377 405
378 if (l == 126) 406 if (len == 126)
379 { 407 {
380 l = (ws_inbuf [2] << 8) | ws_inbuf [3]; 408 len = (ws_inbuf [2] << 8) | ws_inbuf [3];
381 d += 2; 409 d += 2;
382 } 410 }
383 else if (l == 127) 411 else if (len == 127)
384 { 412 {
385 if (ws_inbuf_len < 2 + 8) 413 if (ws_inbuf_len < 2 + 8)
386 return; 414 return;
387 415
388 // we don't do extra long frames, if a browser wants to send >2**32 bytes, 416 // we don't do extra long frames, if a browser wants to send >2**32 bytes,
389 // there are bigger issues to fix. 417 // there are bigger issues to fix.
390 l = (ws_inbuf [6] << 24) 418 len = (ws_inbuf [8] << 8) | ws_inbuf [9];
391 | (ws_inbuf [7] << 16)
392 | (ws_inbuf [8] << 8)
393 | ws_inbuf [9];
394 d += 8; 419 d += 8;
395 } 420 }
396 421
397 // we only continue if we have a complete frame 422 // we only continue if we have a complete frame
398 if (ws_inbuf_len < d + 4 + l) 423 if (ws_inbuf_len < d + 4 + len)
399 return; 424 return;
400 425
401 switch (o) 426 switch (op)
402 { 427 {
403 case 0: o = ws_inbuf_type; break; // continuation 428 case 0: op = ws_inbuf_type; break; // continuation
404 case 1: ws_inbuf_type = 1; break; // utf-8 429 case 1: ws_inbuf_type = 1; break; // utf-8
405 case 2: ws_inbuf_type = 2; break; // binary 430 case 2: ws_inbuf_type = 2; break; // binary
406 } 431 }
407 432
408 if (l > amount) 433 if (len > sizeof (inbuf) - inbuf_len)
409 { 434 {
410 // input buffer full 435 // input buffer full
411 LOG (llevError, "input buffer overflow (ws)."); 436 LOG (llevError, "input buffer overflow (ws).");
412 destroy (); 437 destroy ();
413 return; 438 return;
414 } 439 }
415 440
441 uint8 *buf = inbuf + inbuf_len + 2;
442
416 for (int i = 0; i < l; ++i) 443 for (int i = 0; i < len; ++i)
417 inbuf [inbuf_len + i] = ws_inbuf [d + 4 + i] ^ ws_inbuf [d + (i & 3)]; 444 buf [i] = ws_inbuf [d + 4 + i] ^ ws_inbuf [d + (i & 3)];
418 445
419 // remove frame 446 // remove frame
420 ws_inbuf_len -= d + 4 + l; 447 ws_inbuf_len -= d + 4 + len;
421 memmove (ws_inbuf, ws_inbuf + d + 4 + l, ws_inbuf_len); 448 memmove (ws_inbuf, ws_inbuf + d + 4 + len, ws_inbuf_len);
422 449
423 switch (o) 450 switch (op)
424 { 451 {
425 case 1: // utf-8 452 case 1: // utf-8
453 // utf-8 encoded frames cannot have full length (MAXSOCKBUF) in all cases
454 // but we assume that these extra-long packets will be rare.
426 { 455 {
427 uint8 *a = inbuf + inbuf_len; 456 uint8 *a = buf;
428 uint8 *b = a; 457 uint8 *b = a;
429 uint8 *c = a + l; 458 uint8 *c = a + len;
430 459
431 for (; a < c; ++a, ++b) 460 for (; a < c; ++a, ++b)
432 { 461 {
433 *b = *a; 462 *b = *a;
434 463
435 if (*a >= 0x80) 464 if (*a >= 0x80)
436 *b = (a [0] & 0x1f) << 6 | (a [1] & 0x3f), ++a; 465 *b = (a [0] & 0x1f) << 6 | (a [1] & 0x3f), ++a;
437 } 466 }
438 467
439 l -= a - b; 468 len -= a - b;
440 } 469 }
470 /* FALLTHROUGH */
471 case 2: // binary
472 inbuf_len += len;
473
474 if (fin)
475 {
476 inbuf [0] = inbuf_len >> 8;
477 inbuf [1] = inbuf_len;
478
479 inbuf_len += 2;
480
481 inbuf_handle ();
482 }
441 break; 483 break;
442 case 2: // binary
443 break;
444 484
445 case 9: // ping 485 case 9: // ping
446 { 486 {
447 // send pong - we assume ping messages are <64k 487 // send pong - we assume ping messages are <64k
448 // as we can't handle >10k at the moment anyway. 488 // as we can't handle >10k at the moment anyway.
449 uint8 hdr [] = { 0x8a, 126, l >> 8, l }; 489 uint8 hdr [] = { 0x8a, 126, len >> 8, len };
450 send (hdr, sizeof (hdr)); 490 send (hdr, sizeof (hdr));
451 send (inbuf + inbuf_len, l); 491 send (inbuf + inbuf_len, len);
452 } 492 }
453 return; 493 break;
454 494
455 case 10: // pong 495 case 10: // pong
456 return; 496 break;
457 497
458 case 8: // close 498 case 8: // close
459 default: 499 default:
460 destroy (); 500 destroy ();
461 return; 501 return;
462 } 502 }
463
464 amount = l;
465 } 503 }
466 else
467 amount = -1;
468 }
469 else
470 amount = read (fd, inbuf + inbuf_len, amount);
471
472 if (!amount)
473 {
474 destroy ();
475 return;
476 }
477 else if (amount < 0)
478 {
479 if (errno != EAGAIN && errno != EINTR)
480 {
481 LOG (llevError, "read error: %s\n", strerror (errno));
482 destroy ();
483 return;
484 }
485
486 // should not be here, normally
487 } 504 }
488 else 505 else
489 { 506 {
490 inbuf_len += amount; 507 inbuf_len += amount;
491 inbuf_handle (); 508 inbuf_handle ();
584 } 601 }
585 } 602 }
586 603
587 assert (b - buf < sizeof (buf)); 604 assert (b - buf < sizeof (buf));
588 605
589 int l = b - (buf + 4); 606 int len = b - (buf + 4);
590 607
591 if (l < 126) 608 if (len < 126)
592 { 609 {
593 buf [2] = 0x81; 610 buf [2] = 0x81;
594 buf [3] = l; 611 buf [3] = len;
595 612
596 send (buf + 2, l + 2); 613 send (buf + 2, len + 2);
597 } 614 }
598 else 615 else
599 { 616 {
600 buf [0] = 0x81; 617 buf [0] = 0x81;
601 buf [1] = 126; 618 buf [1] = 126;
602 buf [2] = l >> 8; 619 buf [2] = len >> 8;
603 buf [3] = l; 620 buf [3] = len;
604 621
605 send (buf, l + 4); 622 send (buf, len + 4);
606 } 623 }
607 } 624 }
608 else if (ws_version == 13) 625 else if (ws_version == 13)
609 { 626 {
610 int l = sl.length (); 627 int len = sl.length ();
611 628
612 if (l < 126) 629 if (len < 126)
613 { 630 {
614 uint8 hdr [] = { 0x82, l }; 631 uint8 hdr [] = { 0x82, len };
615 send (hdr, sizeof (hdr)); 632 send (hdr, sizeof (hdr));
616 } 633 }
617 else 634 else
618 { 635 {
619 uint8 hdr [] = { 0x82, 126, l >> 8, l }; 636 uint8 hdr [] = { 0x82, 126, len >> 8, len };
620 send (hdr, sizeof (hdr)); 637 send (hdr, sizeof (hdr));
621 } 638 }
622 639
623 send (sl.buf_ + sl.hdrlen, l); 640 send (sl.buf_ + sl.hdrlen, len);
624 } 641 }
625 else 642 else
626 { 643 {
627 assert (sl.hdrlen == 2); 644 assert (sl.hdrlen == 2);
628 645

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines