Changeset dce3903 for protocols/jabber/s5bytestream.c
- Timestamp:
- 2007-12-04T00:48:57Z (16 years ago)
- Branches:
- master
- Children:
- 8076ec0, fa30fa5
- Parents:
- 2ff2076
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
protocols/jabber/s5bytestream.c
r2ff2076 rdce3903 72 72 return jabber_bs_abort( bt , msg ": %s", strerror( errno ) ); 73 73 74 #define JABBER_BS_BUFSIZE 6553675 76 74 gboolean jabber_bs_abort( struct bs_transfer *bt, char *format, ... ); 77 75 void jabber_bs_canceled( file_transfer_t *ft , char *reason ); … … 83 81 void jabber_bs_recv_answer_request( struct bs_transfer *bt ); 84 82 gboolean jabber_bs_recv_read( gpointer data, gint fd, b_input_condition cond ); 85 void jabber_bs_recv_out_of_data( file_transfer_t *ft );83 gboolean jabber_bs_recv_write_request( file_transfer_t *ft ); 86 84 gboolean jabber_bs_recv_handshake( gpointer data, gint fd, b_input_condition cond ); 87 85 gboolean jabber_bs_recv_handshake_abort( struct bs_transfer *bt, char *error ); … … 109 107 xt_free_node( bt->qnode ); 110 108 g_free( bt ); 111 //iq_id 109 112 110 jabber_si_free_transfer( ft ); 113 111 } … … 326 324 sock_make_nonblocking( fd ); 327 325 328 imcb_log( bt->tf->ic, " Transferring file %s: Connecting to streamhost %s:%s", bt->tf->ft->file_name, host, port );326 imcb_log( bt->tf->ic, "File %s: Connecting to streamhost %s:%s", bt->tf->ft->file_name, host, port ); 329 327 330 328 if( ( connect( fd, rp->ai_addr, rp->ai_addrlen ) == -1 ) && … … 426 424 jabber_bs_recv_answer_request( bt ); 427 425 428 // reset in answer_request bt->tf->watch_in = 0;429 426 return FALSE; 430 427 } … … 441 438 * If the handshake failed we can try the next streamhost, if there is one. 442 439 * An intelligent sender would probably specify himself as the first streamhost and 443 * a proxy as the second (Kopete is an example here). That way, a (potentially) 444 * slow proxy is only used if neccessary. 440 * a proxy as the second (Kopete and PSI are examples here). That way, a (potentially) 441 * slow proxy is only used if neccessary. This of course also means, that the timeout 442 * per streamhost should be kept short. If one or two firewalled adresses are specified, 443 * they have to timeout first before a proxy is tried. 445 444 */ 446 445 gboolean jabber_bs_recv_handshake_abort( struct bs_transfer *bt, char *error ) … … 494 493 struct xt_node *reply; 495 494 496 imcb_log( tf->ic, " Transferring file %s: established SOCKS5 connection to %s:%s",495 imcb_log( tf->ic, "File %s: established SOCKS5 connection to %s:%s", 497 496 tf->ft->file_name, 498 497 xt_find_attr( bt->shnode, "host" ), … … 501 500 tf->ft->data = tf; 502 501 tf->ft->started = time( NULL ); 503 tf->watch_in = b_input_add( tf->fd, GAIM_INPUT_READ, jabber_bs_recv_read, tf);504 tf->ft-> out_of_data = jabber_bs_recv_out_of_data;502 tf->watch_in = b_input_add( tf->fd, GAIM_INPUT_READ, jabber_bs_recv_read, bt ); 503 tf->ft->write_request = jabber_bs_recv_write_request; 505 504 506 505 reply = xt_new_node( "streamhost-used", NULL, NULL ); … … 519 518 } 520 519 521 /* Reads till it is unscheduled or the receiver signifies an overflow. */ 520 /* 521 * This function is called from write_request directly. If no data is available, it will install itself 522 * as a watcher for input on fd and once that happens, deliver the data and unschedule itself again. 523 */ 522 524 gboolean jabber_bs_recv_read( gpointer data, gint fd, b_input_condition cond ) 523 525 { 524 526 int ret; 525 struct jabber_transfer *tf = data; 526 struct bs_transfer *bt = tf->streamhandle; 527 char *buffer = g_malloc( JABBER_BS_BUFSIZE ); 528 529 if (tf->receiver_overflow) 530 { 531 if( tf->watch_in ) 527 struct bs_transfer *bt = data; 528 struct jabber_transfer *tf = bt->tf; 529 530 if( fd != 0 ) /* called via event thread */ 531 { 532 tf->watch_in = 0; 533 ASSERTSOCKOP( ret = recv( fd, tf->ft->buffer, sizeof( tf->ft->buffer ), 0 ) , "Receiving" ); 534 } 535 else 536 { 537 /* called directly. There might not be any data available. */ 538 if( ( ( ret = recv( tf->fd, tf->ft->buffer, sizeof( tf->ft->buffer ), 0 ) ) == -1 ) && 539 ( errno != EAGAIN ) ) 540 return jabber_bs_abort( bt, "Receiving: %s", strerror( errno ) ); 541 542 if( ( ret == -1 ) && ( errno == EAGAIN ) ) 532 543 { 533 /* should never happen, BUG */ 534 imcb_file_canceled( tf->ft, "Bug in jabber file transfer code: read while overflow is true. Please report" ); 544 tf->watch_in = b_input_add( tf->fd, GAIM_INPUT_READ, jabber_bs_recv_read, bt ); 535 545 return FALSE; 536 546 } 537 547 } 538 548 539 ASSERTSOCKOP( ret = recv( fd, buffer, JABBER_BS_BUFSIZE, 0 ) , "Receiving" ); 540 541 /* that should be all */ 549 /* shouldn't happen since we know the file size */ 542 550 if( ret == 0 ) 551 return jabber_bs_abort( bt, "Remote end closed connection" ); 552 553 tf->bytesread += ret; 554 555 tf->ft->write( tf->ft, tf->ft->buffer, ret ); 556 557 return FALSE; 558 } 559 560 /* 561 * imc callback that is invoked when it is ready to receive some data. 562 */ 563 gboolean jabber_bs_recv_write_request( file_transfer_t *ft ) 564 { 565 struct jabber_transfer *tf = ft->data; 566 567 if( tf->watch_in ) 568 { 569 imcb_file_canceled( ft, "BUG in jabber file transfer: write_request called when already watching for input" ); 543 570 return FALSE; 544 545 tf->bytesread += ret; 546 547 buffer = g_realloc( buffer, ret ); 548 549 if ( ( tf->receiver_overflow = imcb_file_write( tf->ft, buffer, ret ) ) ) 550 { 551 /* wait for imcb to run out of data */ 552 tf->watch_in = 0; 553 return FALSE; 554 } 555 571 } 572 573 jabber_bs_recv_read( tf->streamhandle, 0 , 0 ); 574 556 575 return TRUE; 557 576 } 558 577 559 /* imcb callback that is invoked when it runs out of data. 560 * We reschedule jabber_bs_read here if neccessary. */ 561 void jabber_bs_recv_out_of_data( file_transfer_t *ft ) 562 { 563 struct jabber_transfer *tf = ft->data; 564 565 tf->receiver_overflow = FALSE; 566 567 if ( !tf->watch_in ) 568 tf->watch_in = b_input_add( tf->fd, GAIM_INPUT_READ, jabber_bs_recv_read, tf ); 569 } 570 571 /* signal ood and be done */ 578 /* 579 * Issues a write_request to imc. 580 * */ 572 581 gboolean jabber_bs_send_can_write( gpointer data, gint fd, b_input_condition cond ) 573 582 { 574 583 struct bs_transfer *bt = data; 575 584 576 bt->tf->ft->out_of_data( bt->tf->ft );577 578 585 bt->tf->watch_out = 0; 586 587 bt->tf->ft->write_request( bt->tf->ft ); 588 579 589 return FALSE; 580 590 } 581 591 582 /* try to send the stuff. If you can't return false and wait for writable */ 583 gboolean jabber_bs_send_write( file_transfer_t *ft, char *buffer, int len ) 592 /* 593 * This should only be called if we can write, so just do it. 594 * Add a write watch so we can write more during the next cycle (if possible). 595 */ 596 gboolean jabber_bs_send_write( file_transfer_t *ft, char *buffer, unsigned int len ) 584 597 { 585 598 struct jabber_transfer *tf = ft->data; … … 587 600 int ret; 588 601 589 if ( ( ( ret = send( tf->fd, buffer, len, 0 ) ) == -1 ) &&590 ( errno != EAGAIN ) )591 return jabber_bs_abort( bt, "send failed on socket with: %s", strerror( errno ) );592 593 if( ret == 0 ) 594 return jabber_bs_abort( bt, "Remote end closed connection" );595 596 if( ret == -1 )597 {598 bt->tf->watch_out = b_input_add( tf->fd, GAIM_INPUT_WRITE, jabber_bs_send_can_write, bt);599 return FALSE; 600 }602 if( tf->watch_out ) 603 return jabber_bs_abort( bt, "BUG: write() called while watching " ); 604 605 ASSERTSOCKOP( ret = send( tf->fd, buffer, len, 0 ), "Sending" ); 606 607 tf->byteswritten += ret; 608 609 /* TODO: this should really not be fatal */ 610 if( ret < len ) 611 return jabber_bs_abort( bt, "send() sent %d instead of %d (send buffer too big!)", ret, len ); 612 613 bt->tf->watch_out = b_input_add( tf->fd, GAIM_INPUT_WRITE, jabber_bs_send_can_write, bt ); 601 614 602 615 return TRUE; 603 616 } 604 617 618 /* 619 * Handles the reply by the receiver containing the used streamhost. 620 */ 605 621 static xt_status jabber_bs_send_handle_reply(struct im_connection *ic, struct xt_node *node, struct xt_node *orig ) { 606 622 struct jabber_transfer *tf = NULL; … … 651 667 if( bt->phase == BS_PHASE_REPLY ) 652 668 { 669 /* handshake went through, let's start transferring */ 653 670 tf->ft->started = time( NULL ); 654 tf->ft->out_of_data( tf->ft ); 655 } 656 657 //bt->tf->watch_out = b_input_add( tf->fd, GAIM_INPUT_WRITE, jabber_bs_send_write, tf ); 671 tf->ft->write_request( tf->ft ); 672 } 658 673 659 674 return XT_HANDLED; … … 681 696 bt = g_new0( struct bs_transfer, 1 ); 682 697 bt->tf = tf; 683 //bt->qnode = xt_dup( qnode );684 //bt->shnode = bt->qnode->children;685 698 bt->phase = BS_PHASE_CONNECT; 686 699 bt->pseudoadr = g_strdup( hash_hex ); … … 714 727 iq = jabber_make_packet( "iq", "set", tf->tgt_jid, query ); 715 728 xt_add_attr( iq, "from", tf->ini_jid ); 716 717 //xt_free_node( query );718 729 719 730 jabber_cache_add( tf->ic, iq, jabber_bs_send_handle_reply ); … … 885 896 bt->phase = BS_PHASE_REPLY; 886 897 887 /* don't start sending till the streamhost-used message comes in */ 898 imcb_log( tf->ic, "File %s: SOCKS5 handshake successful! Transfer about to start...", tf->ft->file_name ); 899 888 900 if( tf->accepted ) 889 901 { 902 /* streamhost-used message came already in(possible?), let's start sending */ 890 903 tf->ft->started = time( NULL ); 891 tf->ft-> out_of_data( tf->ft );904 tf->ft->write_request( tf->ft ); 892 905 } 893 906
Note: See TracChangeset
for help on using the changeset viewer.