607
607
GlobusResult res;
608
608
DataStatus result = DataStatus::ListError;
609
if (send_command("PASV", NULL, true, &sresp, NULL, '(') !=
610
pasv_addr.hostlen = 0;
611
// Try EPSV first to make it work over IPv6
612
if (send_command("EPSV", NULL, true, &sresp, NULL, '(') !=
610
613
GLOBUS_FTP_POSITIVE_COMPLETION_REPLY) {
612
logger.msg(INFO, "PASV failed: %s", sresp);
613
result.SetDesc("PASV comand failed at "+urlstr+" : "+sresp);
615
logger.msg(INFO, "EPSV failed: %s", sresp);
616
result.SetDesc("EPSV comand failed at "+urlstr+" : "+sresp);
616
logger.msg(INFO, "PASV failed");
617
result.SetDesc("PASV comand failed at "+urlstr);
623
int port_low, port_high;
624
if (sscanf(sresp, "%i,%i,%i,%i,%i,%i",
625
&(pasv_addr.host[0]), &(pasv_addr.host[1]),
626
&(pasv_addr.host[2]), &(pasv_addr.host[3]),
627
&port_high, &port_low) == 6)
628
pasv_addr.port = ((port_high & 0x000FF) << 8) | (port_low & 0x000FF);
630
if (pasv_addr.port == 0) {
631
logger.msg(INFO, "Can't parse host and port in response to PASV");
632
result.SetDesc("Can't parse host and port in response to PASV from "+urlstr);
633
if (sresp) free(sresp);
637
logger.msg(VERBOSE, "Data channel: %d.%d.%d.%d %d", pasv_addr.host[0],
638
pasv_addr.host[1], pasv_addr.host[2], pasv_addr.host[3],
619
logger.msg(INFO, "EPSV failed");
620
result.SetDesc("EPSV comand failed at "+urlstr);
622
// Now try PASV. It will fail on IPv6 unless server provides IPv4 data channel.
623
if (send_command("PASV", NULL, true, &sresp, NULL, '(') !=
624
GLOBUS_FTP_POSITIVE_COMPLETION_REPLY) {
626
logger.msg(INFO, "PASV failed: %s", sresp);
627
result.SetDesc("PASV comand failed at "+urlstr+" : "+sresp);
630
logger.msg(INFO, "PASV failed");
631
result.SetDesc("PASV comand failed at "+urlstr);
636
int port_low, port_high;
637
if (sscanf(sresp, "%i,%i,%i,%i,%i,%i",
638
&(pasv_addr.host[0]), &(pasv_addr.host[1]),
639
&(pasv_addr.host[2]), &(pasv_addr.host[3]),
640
&port_high, &port_low) == 6) {
641
pasv_addr.port = ((port_high & 0x000FF) << 8) | (port_low & 0x000FF);
642
pasv_addr.hostlen = 4;
647
// Successful EPSV - response is (|||port|)
648
// Currently more complex responses with protocol and host
649
// are not supported.
654
if((sresp[1] == sep) && (sresp[2] == sep) &&
655
((lsep = (char*)strchr(sresp+3,sep)) != NULL)) {
657
pasv_addr.port = strtoul(sresp+3,&lsep,10);
658
if(pasv_addr.port != 0) {
659
// Apply control connection address
660
unsigned short local_port;
661
if(!(res = globus_io_tcp_get_remote_address_ex(&(handle->cc_handle.io_handle),
662
pasv_addr.host,&pasv_addr.hostlen,&local_port))) {
663
logger.msg(INFO, "Failed to apply local address to data connection");
664
std::string globus_err(res.str());
665
logger.msg(INFO, "Failure: %s", globus_err);
666
result.SetDesc("Failed to apply local address to data connection for "+urlstr+": "+globus_err);
676
if (pasv_addr.hostlen == 0) {
677
logger.msg(INFO, "Can't parse host and/or port in response to EPSV/PASV");
678
result.SetDesc("Can't parse host and/or port in response to EPSV/PASV from "+urlstr);
681
if (pasv_addr.hostlen == 4) {
682
logger.msg(VERBOSE, "Data channel: %d.%d.%d.%d:%d",
683
pasv_addr.host[0], pasv_addr.host[1], pasv_addr.host[2], pasv_addr.host[3],
687
snprintf(buf,sizeof(buf),"%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x",
688
pasv_addr.host[0]<<8 | pasv_addr.host[1],
689
pasv_addr.host[2]<<8 | pasv_addr.host[3],
690
pasv_addr.host[4]<<8 | pasv_addr.host[5],
691
pasv_addr.host[6]<<8 | pasv_addr.host[7],
692
pasv_addr.host[8]<<8 | pasv_addr.host[9],
693
pasv_addr.host[10]<<8 | pasv_addr.host[11],
694
pasv_addr.host[12]<<8 | pasv_addr.host[13],
695
pasv_addr.host[14]<<8 | pasv_addr.host[15]);
696
buf[sizeof(buf)-1] = 0;
697
logger.msg(VERBOSE, "Data channel: [%s]:%d",
698
buf, pasv_addr.port);
640
700
if (!(res = globus_ftp_control_local_port(handle, &pasv_addr))) {
641
701
logger.msg(INFO, "Obtained host and address are not acceptable");
642
702
std::string globus_err(res.str());