### Eclipse Workspace Patch 1.0 #P ecos Index: net/common/current/cdl/net.cdl =================================================================== RCS file: /cvs/ecos/ecos-opt/net/net/common/current/cdl/net.cdl,v retrieving revision 1.17 diff -u -r1.17 net.cdl --- net/common/current/cdl/net.cdl 7 Jan 2007 14:46:55 -0000 1.17 +++ net/common/current/cdl/net.cdl 19 Dec 2007 13:51:55 -0000 @@ -167,6 +167,17 @@ threads can have precedence over TFTP server processing." } + cdl_option CYGPKG_NET_TFTPD_CLIENT_GET_PACKETSIZE { + display "TFTP protocol allows negotiation of bigger packets. + Requires server which supports RFC 2348 blksize negotiation." + flavor data + default_value 512 + legal_values 512 to 65464 + description " + tftp blksize egotiation support. >512 byte block sizes improves + tftp GET performance" + } + cdl_option CYGPKG_NET_TFTPD_THREAD_STACK_SIZE { display "Stack size for TFTP threads." flavor data Index: net/common/current/include/arpa/tftp.h =================================================================== RCS file: /cvs/ecos/ecos-opt/net/net/common/current/include/arpa/tftp.h,v retrieving revision 1.2 diff -u -r1.2 tftp.h --- net/common/current/include/arpa/tftp.h 7 Aug 2002 14:42:35 -0000 1.2 +++ net/common/current/include/arpa/tftp.h 19 Dec 2007 13:51:55 -0000 @@ -70,6 +70,7 @@ #define DATA 03 /* data packet */ #define ACK 04 /* acknowledgement */ #define ERROR 05 /* error code */ +#define OACK 06 /* option acknowledge */ struct tftphdr { short th_opcode; /* packet type */ Index: net/common/current/ChangeLog =================================================================== RCS file: /cvs/ecos/ecos-opt/net/net/common/current/ChangeLog,v retrieving revision 1.81 diff -u -r1.81 ChangeLog --- net/common/current/ChangeLog 15 Jan 2007 18:37:52 -0000 1.81 +++ net/common/current/ChangeLog 19 Dec 2007 13:51:55 -0000 @@ -1,3 +1,8 @@ +2007-12-19 Oyvind Harboe + + * src/tftp_client.c, include/arpa/tftp.h, cdl/net.cdl: tftp blksize + negotiation support. >512 byte block sizes improves tftp GET performance + 2007-01-15 Gary Thomas * src/dhcp_support.c (dhcp_mgt_entry): Better handling when restarting Index: net/common/current/src/tftp_client.c =================================================================== RCS file: /cvs/ecos/ecos-opt/net/net/common/current/src/tftp_client.c,v retrieving revision 1.10 diff -u -r1.10 tftp_client.c --- net/common/current/src/tftp_client.c 16 Sep 2005 14:56:26 -0000 1.10 +++ net/common/current/src/tftp_client.c 19 Dec 2007 13:51:56 -0000 @@ -57,6 +57,8 @@ #include #include #include +#include +#include #define min(x,y) (x512 + if (negotiate) + { + fp="blksize"; + while (*fp) *cp++ = *fp++; + *cp++ = '\0'; + cp+=sprintf(cp, "%d", CYGPKG_NET_TFTPD_CLIENT_GET_PACKETSIZE); + *cp++ = '\0'; + } +#endif memset(&hints,0,sizeof(hints)); hints.ai_family = PF_UNSPEC; @@ -214,15 +228,37 @@ } } } else { - recv_len = sizeof(data); + recv_len = blksize+sizeof(struct tftphdr); from_len = sizeof(from_addr); - if ((data_len = recvfrom(s, &data, recv_len, 0, + if ((data_len = recvfrom(s, data, recv_len, 0, &from_addr, &from_len)) < 0) { // What happened? *err = TFTP_NETERR; goto out; } - if (ntohs(hdr->th_opcode) == DATA) { +#if CYGPKG_NET_TFTPD_CLIENT_GET_PACKETSIZE>512 + if (ntohs(hdr->th_opcode) == OACK) { + // We can have only *one* option, the one we sent.. + if (strncmp(data+2, "blksize", data_len)==0) + { + blksize=atol(data+2+strlen("blksize")+1); + } else + { + // option ignored, use default. + } + // Send out the ACK + hdr->th_opcode = htons(ACK); + hdr->th_block = htons(last_good_block); + if (sendto(s, data, 4 /* FIXME */, 0, + &from_addr, from_len) < 0) { + // Problem sending request + *err = TFTP_NETERR; + goto out; + } + + } else +#endif + if (ntohs(hdr->th_opcode) == DATA) { actual_len = 0; if (ntohs(hdr->th_block) == (last_good_block+1)) { // Consume this data @@ -244,7 +280,7 @@ // To prevent an out-of-sequence packet from // terminating transmission prematurely, set // actual_len to a full size packet. - actual_len = SEGSIZE; + actual_len = blksize; } // Send out the ACK hdr->th_opcode = htons(ACK); @@ -256,7 +292,8 @@ goto out; } // A short packet marks the end of the file. - if ((actual_len >= 0) && (actual_len < SEGSIZE)) { + /* 4 = Sizeof TFTP header */ + if ((actual_len >= 0) && (actual_len < blksize)) { // End of data close(s); freeaddrinfo(res); @@ -290,6 +327,50 @@ freeaddrinfo(res); return -1; } + + +int tftp_client_get(const char * const filename, + const char * const server, + const int port, + char *buf, + int len, + const int mode, + int * const err) { + int result; +#if CYGPKG_NET_TFTPD_CLIENT_GET_PACKETSIZE>512 + char *data = malloc(CYGPKG_NET_TFTPD_CLIENT_GET_PACKETSIZE+ + sizeof(struct tftphdr)); + if (data==NULL) + { + *err=TFTP_ENOSPACE; + return -1; + } +#else + char data[SEGSIZE+sizeof(struct tftphdr)]; +#endif + result=tftp_client_get_inner(data, filename, server, + port, buf, len, mode, err, + CYGPKG_NET_TFTPD_CLIENT_GET_PACKETSIZE>512); + if (result<0) + { +#if CYGPKG_NET_TFTPD_CLIENT_GET_PACKETSIZE>512 + // try without negotiating packet size. The serves that do + // not support options negotiation would normally just ignore + // the options and thus this code path will probably never be + // executed + result=tftp_client_get_inner(data, filename, server, + port, buf, len, mode, err, + 0); +#endif + } + +#if CYGPKG_NET_TFTPD_CLIENT_GET_PACKETSIZE>512 + free(data); +#endif + + return result; +} + // // Read a file from a host into a local buffer. Returns the // number of bytes actually read, or (-1) if an error occurs.