~ubuntu-branches/ubuntu/trusty/nordugrid-arc/trusty

« back to all changes in this revision

Viewing changes to src/hed/dmc/gridftp/Lister.cpp

  • Committer: Package Import Robot
  • Author(s): Mattias Ellert
  • Date: 2013-11-29 13:39:10 UTC
  • mfrom: (3.1.16 sid)
  • Revision ID: package-import@ubuntu.com-20131129133910-sy6ayoavphc5hozs
Tags: 4.0.0-1
4.0.0 Release (Closes: #715131) (LP: #1049798)

Show diffs side-by-side

added added

removed removed

Lines of Context:
606
606
    char *sresp;
607
607
    GlobusResult res;
608
608
    DataStatus result = DataStatus::ListError;
609
 
    if (send_command("PASV", NULL, true, &sresp, NULL, '(') !=
 
609
    pasv_addr.port = 0;
 
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) {
611
614
      if (sresp) {
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);
614
617
        free(sresp);
615
618
      } else {
616
 
        logger.msg(INFO, "PASV failed");
617
 
        result.SetDesc("PASV comand failed at "+urlstr);
618
 
      }
619
 
      return result;
620
 
    }
621
 
    pasv_addr.port = 0;
622
 
    if (sresp) {
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);
629
 
    }
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);
634
 
      return result;
635
 
    }
636
 
    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],
639
 
               pasv_addr.port);
 
619
        logger.msg(INFO, "EPSV failed");
 
620
        result.SetDesc("EPSV comand failed at "+urlstr);
 
621
      }
 
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) {
 
625
        if (sresp) {
 
626
          logger.msg(INFO, "PASV failed: %s", sresp);
 
627
          result.SetDesc("PASV comand failed at "+urlstr+" : "+sresp);
 
628
          free(sresp);
 
629
        } else {
 
630
          logger.msg(INFO, "PASV failed");
 
631
          result.SetDesc("PASV comand failed at "+urlstr);
 
632
        }
 
633
        return result;
 
634
      }
 
635
      if (sresp) {
 
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;
 
643
        }
 
644
        free(sresp);
 
645
      }
 
646
    } else {
 
647
      // Successful EPSV - response is (|||port|)
 
648
      // Currently more complex responses with protocol and host
 
649
      // are not supported.
 
650
      if (sresp) {
 
651
        char sep = sresp[0];
 
652
        char* lsep = NULL;
 
653
        if(sep) {
 
654
          if((sresp[1] == sep) && (sresp[2] == sep) &&
 
655
             ((lsep = (char*)strchr(sresp+3,sep)) != NULL)) {
 
656
            *lsep = 0;
 
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);
 
667
                free(sresp);
 
668
                return result;
 
669
              }
 
670
            }
 
671
          }
 
672
        }
 
673
        free(sresp);
 
674
      }
 
675
    }
 
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);
 
679
      return result;
 
680
    }
 
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],
 
684
                 pasv_addr.port);
 
685
    } else {
 
686
      char buf[8*5];
 
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);
 
699
    }
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());