- Timestamp:
- 2007-12-04T00:48:57Z (17 years ago)
- Branches:
- master
- Children:
- 8076ec0, fa30fa5
- Parents:
- 2ff2076
- Location:
- protocols
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
protocols/ft.h
r2ff2076 rdce3903 26 26 #ifndef _FT_H 27 27 #define _FT_H 28 29 /* 30 * One buffer is needed for each transfer. The receiver stores a message 31 * in it and gives it to the sender. The sender will stall the receiver 32 * till the buffer has been sent out. 33 */ 34 #define FT_BUFFER_SIZE 2048 28 35 29 36 typedef enum { … … 131 138 132 139 /* 133 * If set, called when the transfer queue is running empty and 134 * more data can be added. 140 * called by the sending side to indicate that it is writable. 141 * The callee should check if data is available and call the 142 * function(as seen below) if that is the case. 135 143 */ 136 void (*out_of_data) ( struct file_transfer *file );144 gboolean (*write_request) ( struct file_transfer *file ); 137 145 138 146 /* 139 147 * When sending files, protocols register this function to receive data. 148 * This should only be called once after write_request is called. The caller 149 * should not read more data until write_request is called again. This technique 150 * avoids buffering. 140 151 */ 141 gboolean (*write) (struct file_transfer *file, char *buffer, int len ); 152 gboolean (*write) (struct file_transfer *file, char *buffer, unsigned int len ); 153 154 /* The send buffer associated with this transfer. 155 * Since receivers always wait for a write_request call one is enough. 156 */ 157 char buffer[FT_BUFFER_SIZE]; 142 158 143 159 } file_transfer_t; … … 154 170 void imcb_file_canceled( file_transfer_t *file, char *reason ); 155 171 156 /*157 * The given buffer is queued for transfer and MUST NOT be freed by the caller.158 * When the method returns false the caller should not invoke this method again159 * until out_of_data has been called.160 */161 gboolean imcb_file_write( file_transfer_t *file, gpointer data, size_t data_size );162 163 172 gboolean imcb_file_recv_start( file_transfer_t *ft ); 164 173 #endif -
protocols/jabber/jabber.h
r2ff2076 rdce3903 146 146 147 147 size_t bytesread, byteswritten; 148 int receiver_overflow;149 148 int fd; 150 149 struct sockaddr_storage saddr; … … 209 208 int jabber_bs_recv_request( struct im_connection *ic, struct xt_node *node, struct xt_node *qnode); 210 209 gboolean jabber_bs_send_start( struct jabber_transfer *tf ); 211 gboolean jabber_bs_send_write( file_transfer_t *ft, char *buffer, int len );210 gboolean jabber_bs_send_write( file_transfer_t *ft, char *buffer, unsigned int len ); 212 211 213 212 /* message.c */ -
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 -
protocols/jabber/si.c
r2ff2076 rdce3903 84 84 struct jabber_data *jd = ic->proto_data; 85 85 86 imcb_log( ic, " Incoming file from %s : %s %zd bytes", ic->irc->nick, ft->file_name, ft->file_size);86 imcb_log( ic, "Trying to send %s(%zd bytes) to %s", ft->file_name, ft->file_size, who ); 87 87 88 88 tf = g_new0( struct jabber_transfer, 1 ); … … 224 224 225 225 /* 226 * imc bcalled the accept callback which probably means that the user accepted this file transfer.226 * imc called the accept callback which probably means that the user accepted this file transfer. 227 227 * We send our response to the initiator. 228 228 * In the next step, the initiator will send us a request for the given stream type. … … 275 275 { 276 276 struct xt_node *c, *d; 277 char *ini_jid, *tgt_jid ;277 char *ini_jid, *tgt_jid, *iq_id; 278 278 GSList *tflist; 279 279 struct jabber_transfer *tf=NULL; 280 280 struct jabber_data *jd = ic->proto_data; 281 char *sid;282 281 283 282 if( !( tgt_jid = xt_find_attr( node, "from" ) ) || … … 288 287 } 289 288 290 imcb_log( ic, "GOT RESPONSE TO FILE" );291 289 /* All this means we expect something like this: ( I think ) 292 * <iq from=... to=... >290 * <iq from=... to=... id=...> 293 291 * <si xmlns=si> 294 * <file xmlns=ft/>292 * [ <file xmlns=ft/> ] <-- not neccessary 295 293 * <feature xmlns=feature> 296 294 * <x xmlns=xdata type=submit> … … 300 298 if( !( tgt_jid = xt_find_attr( node, "from" ) ) || 301 299 !( ini_jid = xt_find_attr( node, "to" ) ) || 300 !( iq_id = xt_find_attr( node, "id" ) ) || 302 301 !( c = xt_find_node( node->children, "si" ) ) || 303 302 !( strcmp( xt_find_attr( c, "xmlns" ), XMLNS_SI ) == 0 ) || 304 !( sid = xt_find_attr( c, "id" ) )|| 305 !( d = xt_find_node( c->children, "file" ) ) || 306 !( strcmp( xt_find_attr( d, "xmlns" ), XMLNS_FILETRANSFER ) == 0 ) || 303 /* !( d = xt_find_node( c->children, "file" ) ) || 304 !( strcmp( xt_find_attr( d, "xmlns" ), XMLNS_FILETRANSFER ) == 0 ) || */ 307 305 !( d = xt_find_node( c->children, "feature" ) ) || 308 306 !( strcmp( xt_find_attr( d, "xmlns" ), XMLNS_FEATURE ) == 0 ) || … … 331 329 { 332 330 struct jabber_transfer *tft = tflist->data; 333 if( ( strcmp( tft-> sid, sid ) == 0 ) )331 if( ( strcmp( tft->iq_id, iq_id ) == 0 ) ) 334 332 { 335 333 tf = tft; … … 346 344 tf->ini_jid = g_strdup( ini_jid ); 347 345 tf->tgt_jid = g_strdup( tgt_jid ); 346 347 imcb_log( ic, "File %s: %s accepted the transfer!", tf->ft->file_name, tgt_jid ); 348 348 349 349 jabber_bs_send_start( tf ); … … 423 423 node = jabber_make_packet( "iq", "set", bud ? bud->full_jid : who, sinode ); 424 424 jabber_cache_add( ic, node, jabber_si_handle_response ); 425 tf->iq_id = g_strdup( xt_find_attr( node, "id" ) ); 425 426 426 427 return jabber_write_packet( ic, node );
Note: See TracChangeset
for help on using the changeset viewer.