freetds AT lists.ibiblio.org
Subject: FreeTDS Development Group
List archive
[freetds] seems dblib can get TDS protocol wrong in unusual case
- From: "Hayes, Ted (London)" <rogercarlton_hayes AT ml.com>
- To: <freetds AT lists.ibiblio.org>
- Subject: [freetds] seems dblib can get TDS protocol wrong in unusual case
- Date: Tue, 11 Nov 2008 12:02:14 -0000
Hi
I am running FreeTDS stable (0.82) on Solaris9 32-bit, built using the
Studio 11 compiler. My problem is that in some cases I am unable to
retrieve results returned from execution of certain queries involving
simple stored procedures. The packet returned from the server looks
valid to me - I think that there may be a small hole in FreeTDS
processing of the stream in this particular case.
The server is Sybase ASE v12.5.4/EBF on Solaris 8. The client code
basically executes
dbcancel(dbproc);
dbcmd(dbproc, "exec mysp @param='X'");
dbsqlexec(dbproc);
dbresults();
I've no idea what's happening inside the stored proc, but the data
received is as follows:
net.c:671:Received packet
0000 ff 00 51 00 02 00 00 00-01 ff 00 41 00 02 00 00 |..Q..... ...A....|
0010 00 00 ff 00 51 00 02 00-00 00 01 ff 00 51 00 02 |....Q... .....Q..|
0020 00 00 00 01 ff 00 41 00-02 00 00 00 00 ff 00 51 |......A. .......Q|
0030 00 02 00 00 00 01 ff 00-51 00 02 00 00 00 01 ff |........ Q.......|
0040 00 41 00 02 00 00 00 00-ff 00 51 00 02 00 00 00 |.A...... ..Q.....|
0050 01 ff 00 41 00 02 00 00-00 00 ff 00 51 00 02 00 |...A.... ....Q...|
0060 00 00 01 ff 00 51 00 02-00 00 00 01 ff 00 41 00 |.....Q.. ......A.|
0070 02 00 00 00 00 ff 00 51-00 02 00 00 00 01 ff 00 |.......Q ........|
0080 51 00 02 00 00 00 01 ff-00 41 00 02 00 00 00 00 |Q....... .A......|
0090 ff 00 41 00 02 00 00 00-00 ff 00 51 00 02 00 00 |..A..... ...Q....|
00a0 00 01 ff 00 51 00 02 00-00 00 01 ff 00 51 00 02 |....Q... .....Q..|
00b0 00 00 00 01 ff 00 41 00-02 00 00 00 00 ff 00 51 |......A. .......Q|
00c0 00 02 00 00 00 01 ff 00-41 00 02 00 00 00 00 ff |........ A.......|
00d0 00 51 00 02 00 00 00 01-ff 00 41 00 02 00 00 00 |.Q...... ..A.....|
00e0 01 ff 00 51 00 02 00 00-00 01 fe 00 09 00 02 00 |...Q.... ........|
00f0 00 00 01 ff 00 41 00 02-00 00 00 00 ff 00 41 00 |.....A.. ......A.|
0100 02 00 00 00 00 ff 00 51-00 02 00 00 00 01 ff 00 |.......Q ........|
0110 51 00 02 00 00 00 01 ff-00 41 00 02 00 00 00 00 |Q....... .A......|
0120 ff 00 41 00 02 00 00 00-00 ff 00 41 00 02 00 00 |..A..... ...A....|
0130 00 00 ff 00 41 00 02 00-00 00 00 ff 00 51 00 02 |....A... .....Q..|
0140 00 00 00 01 ff 00 51 00-02 00 00 00 01 ff 00 41 |......Q. .......A|
0150 00 02 00 00 00 00 ff 00-41 00 02 00 00 00 00 ff |........ A.......|
0160 00 41 00 02 00 00 00 00-ff 00 41 00 02 00 00 00 |.A...... ..A.....|
0170 00 7c 36 f1 19 65 00 00-00 00 a0 00 0b 0a 76 65 |.|6..e.. ......ve|
0180 72 73 69 6f 6e 53 74 72-a1 00 06 00 00 00 02 27 |rsionStr .......'|
0190 3d ae 00 01 00 d1 11 32-30 30 36 31 31 31 33 5f |=......2 0061113_|
01a0 31 36 3a 33 37 3a 31 31-ff 00 51 00 02 00 00 00 |16:37:11 ..Q.....|
01b0 01 ff 00 51 00 02 00 00-00 01 79 00 00 00 00 fe |...Q.... ..y.....|
01c0 00 08 00 02 00 00 00 01- |........|
What happens next is that dbsqlok() makes 27 invocations of
tds_process_tokens(). The first 26 process the 0xff markers
(DONEINPROC) and the last marker processed is the 0xfe (DONEPROC) at
packet offset 0xea. tds_process_tokens() calls tds_process_end() and
returns TDS_SUCCEED with result_type = TDS_DONEPROC_RESULT and
done_flags (read from the smallint following the marker) = 0x0009
(TDS_DONE_MORE_RESULTS | TDS_DONE_PROC).
The problem is that dbsqlok() processes the TDS_DONEPROC_RESULT and with
no error flag set in done_flags, sets dbproc->dbresults_state to
_DB_RES_SUCCEED and exits. This just makes the subsequent dbresults()
invocation exit immediately, and the results from the second half of the
packet are lost. From the TDS specification, it seems to me that maybe
the TDS_DONE_MORE_RESULTS bit in done_flags should cause dbsqlok() to
continue looping to make further tds_process_tokens() invocations.
I added this at line 4601 of dblib.c
if (done_flags & TDS_DONE_MORE_RESULTS)
{ break; }
/* else continue with existing code..*/
tdsdump_log(...
dbproc->dbresults_state = _DB_RES_SUCCEED;
With this change, dbsqlok() carries on and processes additional tokens
including the 0x7c (PROCID) at offset 0x171, the 0xa0 (COLNAME) at 0x17a
and 0xa1 (COLFMT) at 0x188. dbsqlok() exits when the 0xae result token
is encountered at 0x191 and dbresults() then successfully processes the
rest of the packet.
I am interested in the opinions of FreeTDS developers of this change -
Is this the right approach or have I got the protocol wrong?
Note - I think that FreeTDS v0.64 has the same issue. The program works
in FreeTDS v0.60, which has much less developed processing of return
codes etc. However from the log I think that with v0.60, the extra TDS
tokens that should be eaten by dbsqlok() are in fact being processed by
dbresults()..
Many thanks and regards
Ted Hayes
--------------------------------------------------------
This message w/attachments (message) may be privileged, confidential or
proprietary, and if you are not an intended recipient, please notify the
sender, do not use or share it and delete it. Unless specifically indicated,
this message is not an offer to sell or a solicitation of any investment
products or other financial product or service, an official confirmation of
any transaction, or an official statement of Merrill Lynch. Subject to
applicable law, Merrill Lynch may monitor, review and retain e-communications
(EC) traveling through its networks/systems. The laws of the country of each
sender/recipient may impact the handling of EC, and EC may be archived,
supervised and produced in countries other than the country in which you are
located. This message cannot be guaranteed to be secure or error-free. This
message is subject to terms available at the following link:
http://www.ml.com/e-communications_terms/. By messaging with Merrill Lynch
you consent to the foregoing.
--------------------------------------------------------
-
[freetds] seems dblib can get TDS protocol wrong in unusual case,
Hayes, Ted (London), 11/11/2008
- Re: [freetds] seems dblib can get TDS protocol wrong in unusual case, James K. Lowden, 11/11/2008
Archive powered by MHonArc 2.6.24.