- Timestamp:
- 2007-12-04T00:48:57Z (16 years ago)
- Branches:
- master
- Children:
- 8076ec0, fa30fa5
- Parents:
- 2ff2076
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
dcc.c
r2ff2076 rdce3903 61 61 unsigned int receivedchunks=0, receiveddata=0; 62 62 63 /*64 * If using DCC SEND AHEAD this value will be set before the first transfer starts.65 * Not that in this case it degenerates to the maximum message size to send() and66 * has nothing to do with packets.67 */68 #ifdef DCC_SEND_AHEAD69 int max_packet_size = DCC_PACKET_SIZE;70 #else71 63 int max_packet_size = 0; 72 #endif73 64 74 65 static void dcc_finish( file_transfer_t *file ); … … 79 70 gboolean dccs_recv_start( file_transfer_t *ft ); 80 71 gboolean dccs_recv_proto( gpointer data, gint fd, b_input_condition cond); 81 void dccs_recv_out_of_data( file_transfer_t *ft );72 gboolean dccs_recv_write_request( file_transfer_t *ft ); 82 73 83 74 /* As defined in ft.h */ … … 100 91 101 92 dcc_close( file ); 102 }103 104 /* As defined in ft.h */105 gboolean imcb_file_write( file_transfer_t *file, gpointer data, size_t data_size )106 {107 return dccs_send_write( file, data, data_size );108 93 } 109 94 … … 139 124 df = dcc_alloc_transfer( file_name, file_size, ic ); 140 125 file = df->ft; 126 file->write = dccs_send_write; 127 file->sending = TRUE; 141 128 142 129 /* listen and request */ … … 195 182 struct sockaddr_in *saddr_ipv4 = ( struct sockaddr_in *) saddr; 196 183 197 /*198 * this is so ridiculous. We're supposed to convert the address to199 * host byte order!!! Let's exclude anyone running big endian just200 * for the fun of it...201 */202 184 sprintf( ipaddr, "%d", 203 htonl( saddr_ipv4->sin_addr.s_addr ) );185 ntohl( saddr_ipv4->sin_addr.s_addr ) ); 204 186 port = saddr_ipv4->sin_port; 205 187 } else … … 226 208 227 209 g_free( cmd ); 228 229 /* message is sortof redundant cause the users client probably informs him about that. remove? */230 imcb_log( df->ic, "Transferring file %s: Chose local address %s for DCC connection", df->ft->file_name, ipaddr );231 210 232 211 return TRUE; … … 305 284 } 306 285 286 /* 287 * fills max_packet_size with twice the TCP maximum segment size 288 */ 307 289 gboolean dcc_check_maxseg( dcc_file_transfer_t *df, int fd ) 308 290 { 309 #ifdef DCC_SEND_AHEAD310 291 /* 311 292 * use twice the maximum segment size as a maximum for calls to send(). … … 318 299 max_packet_size *= 2; 319 300 } 320 #endif321 301 return TRUE; 322 302 } … … 354 334 355 335 /* IM protocol callback */ 356 357 336 if( file->accept ) 358 337 file->accept( file ); 338 359 339 /* reschedule for reading on new fd */ 360 340 df->watch_in = b_input_add( fd, GAIM_INPUT_READ, dccs_send_proto, df ); … … 400 380 } 401 381 402 #ifndef DCC_SEND_AHEAD403 /* reschedule writer if neccessary */404 if( file->bytes_transferred >= df->bytes_sent &&405 df->watch_out == 0 &&406 df->queued_bytes > 0 ) {407 df->watch_out = b_input_add( fd, GAIM_INPUT_WRITE, dcc_send_proto, df );408 }409 #endif410 382 return TRUE; 411 383 } 412 413 if( revents & POLLOUT )414 {415 struct dcc_buffer *dccb;416 int ret;417 char *msg;418 419 if( df->queued_bytes == 0 )420 {421 /* shouldn't happen */422 imcb_log( df->ic, "WARNING: DCC SEND: write called with empty queue" );423 424 df->watch_out = 0;425 return FALSE;426 }427 428 /* start where we left off */429 if( !( df->queued_buffers ) ||430 !( dccb = df->queued_buffers->data ) )431 return dcc_abort( df, "BUG in DCC SEND: queued data but no buffers" );432 433 msg = dccb->b + df->buffer_pos;434 435 int msgsize = MIN(436 #ifndef DCC_SEND_AHEAD437 file->bytes_transferred + MAX_PACKET_SIZE - df->bytes_sent,438 #else439 max_packet_size,440 #endif441 dccb->len - df->buffer_pos );442 443 if ( msgsize == 0 )444 {445 df->watch_out = 0;446 return FALSE;447 }448 449 ASSERTSOCKOP( ret = send( fd, msg, msgsize, 0 ), "Sending data" );450 451 if( ret == 0 )452 return dcc_abort( df, "Remote end closed connection" );453 454 df->bytes_sent += ret;455 df->queued_bytes -= ret;456 df->buffer_pos += ret;457 458 if( df->buffer_pos == dccb->len )459 {460 df->buffer_pos = 0;461 df->queued_buffers = g_slist_remove( df->queued_buffers, dccb );462 g_free( dccb->b );463 g_free( dccb );464 }465 466 if( ( df->queued_bytes < DCC_QUEUE_THRESHOLD_LOW ) && file->out_of_data )467 file->out_of_data( file );468 469 if( df->queued_bytes > 0 )470 {471 /* Who knows how long the event loop cycle will take,472 * let's just try to send some more now. */473 #ifndef DCC_SEND_AHEAD474 if( df->bytes_sent < ( file->bytes_transferred + max_packet_size ) )475 #endif476 return dccs_send_proto( df, fd, cond );477 }478 479 df->watch_out = 0;480 return FALSE;481 }482 483 /* Send buffer full, come back later */484 384 485 385 return TRUE; … … 509 409 /* watch */ 510 410 df->watch_out = b_input_add( df->fd, GAIM_INPUT_WRITE, dccs_recv_proto, df ); 511 ft-> out_of_data = dccs_recv_out_of_data;411 ft->write_request = dccs_recv_write_request; 512 412 513 413 return TRUE; … … 538 438 if( revents & POLLIN ) 539 439 { 540 char *buffer = g_malloc( 65536 );541 440 int ret, done; 542 441 543 ASSERTSOCKOP( ret = recv( fd, buffer, 65536, 0 ), "Receiving" );442 ASSERTSOCKOP( ret = recv( fd, ft->buffer, sizeof( ft->buffer ), 0 ), "Receiving" ); 544 443 545 444 if( ret == 0 ) 546 445 return dcc_abort( df, "Remote end closed connection" ); 547 548 buffer = g_realloc( buffer, ret );549 446 550 447 df->bytes_sent += ret; … … 561 458 562 459 if ( ackret != 4 ) 563 return dcc_abort( df, "Error sending DCC ACK, sent %d instead of 4 bytes", ret );460 return dcc_abort( df, "Error sending DCC ACK, sent %d instead of 4 bytes", ackret ); 564 461 } 565 462 566 if( !ft->write( df->ft, buffer, ret ) && !done ) 567 { 463 if( !ft->write( df->ft, ft->buffer, ret ) ) 464 return FALSE; 465 466 if( done ) 467 { 468 closesocket( fd ); 469 dcc_finish( ft ); 470 568 471 df->watch_in = 0; 569 472 return FALSE; 570 473 } 571 474 572 if( done ) 573 { 574 closesocket( fd ); 575 dcc_finish( ft ); 576 577 df->watch_in = 0; 578 return FALSE; 579 } 580 581 return TRUE; 582 } 583 584 return TRUE; 585 } 586 587 void dccs_recv_out_of_data( file_transfer_t *ft ) 475 df->watch_in = 0; 476 return FALSE; 477 } 478 479 return TRUE; 480 } 481 482 gboolean dccs_recv_write_request( file_transfer_t *ft ) 588 483 { 589 484 dcc_file_transfer_t *df = ft->priv; 590 485 591 if( !df->watch_in ) 592 df->watch_in = b_input_add( df->fd, GAIM_INPUT_READ, dccs_recv_proto, df ); 486 if( df->watch_in ) 487 return dcc_abort( df, "BUG: write_request() called while watching" ); 488 489 df->watch_in = b_input_add( df->fd, GAIM_INPUT_READ, dccs_recv_proto, df ); 490 491 return TRUE; 492 } 493 494 gboolean dccs_send_can_write( gpointer data, gint fd, b_input_condition cond ) 495 { 496 struct dcc_file_transfer *df = data; 497 df->watch_out = 0; 498 499 df->ft->write_request( df->ft ); 500 return FALSE; 593 501 } 594 502 595 503 /* 596 * Incoming data. Note that the buffer MUST NOT be freed by the caller! 597 * We don't copy the buffer but put it in our queue. 504 * Incoming data. 598 505 * 599 * */600 gboolean dccs_send_write( file_transfer_t *file, gpointer data, unsigned int data_size)506 */ 507 gboolean dccs_send_write( file_transfer_t *file, char *data, unsigned int data_len ) 601 508 { 602 509 dcc_file_transfer_t *df = file->priv; 603 struct dcc_buffer *dccb = g_new0( struct dcc_buffer, 1 );604 605 receivedchunks++; receiveddata += data_ size;606 607 dccb->b = data;608 dccb->len = data_size;609 610 df->queued_buffers = g_slist_append( df->queued_buffers, dccb);611 612 df->queued_bytes += data_size;613 614 if( ( file->status & FT_STATUS_TRANSFERRING ) && 615 #ifndef DCC_SEND_AHEAD 616 ( file->bytes_transferred >= df->bytes_sent ) &&617 #endif 618 ( df->watch_out == 0 ) && 619 ( df->queued_bytes > 0 ) )620 { 621 df->watch_out = b_input_add( df->fd, GAIM_INPUT_WRITE, dccs_send_proto, df );622 }623 624 return df->queued_bytes > DCC_QUEUE_THRESHOLD_HIGH;510 int ret; 511 512 receivedchunks++; receiveddata += data_len; 513 514 if( df->watch_out ) 515 return dcc_abort( df, "BUG: write() called while watching" ); 516 517 ASSERTSOCKOP( ret = send( df->fd, data, data_len, 0 ), "Sending data" ); 518 519 if( ret == 0 ) 520 return dcc_abort( df, "Remote end closed connection" ); 521 522 /* TODO: this should really not be fatal */ 523 if( ret < data_len ) 524 return dcc_abort( df, "send() sent %d instead of %d", ret, data_len ); 525 526 df->bytes_sent += ret; 527 528 if( df->bytes_sent < df->ft->file_size ) 529 df->watch_out = b_input_add( df->fd, GAIM_INPUT_WRITE, dccs_send_can_write, df ); 530 531 return TRUE; 625 532 } 626 533 … … 643 550 b_event_remove( df->watch_out ); 644 551 645 if( df->queued_buffers )646 {647 struct dcc_buffer *dccb;648 GSList *gslist = df->queued_buffers;649 650 for( ; gslist ; gslist = g_slist_next( gslist ) )651 {652 dccb = gslist->data;653 g_free( dccb->b );654 g_free( dccb );655 }656 g_slist_free( df->queued_buffers );657 }658 659 552 df->ic->irc->file_transfers = g_slist_remove( df->ic->irc->file_transfers, file ); 660 553
Note: See TracChangeset
for help on using the changeset viewer.