Skip to Content.
Sympa Menu

freetds - Re: PHP: losing client/server sync after error (cvs, Sybase ASA)

freetds AT lists.ibiblio.org

Subject: FreeTDS Development Group

List archive

Chronological Thread  
  • From: Brian Bruns <camber AT ais.org>
  • To: TDS Development Group <freetds AT franklin.metalab.unc.edu>
  • Subject: Re: PHP: losing client/server sync after error (cvs, Sybase ASA)
  • Date: Mon, 2 Sep 2002 08:10:56 -0400 (EDT)



I think the safe thing to do here is to read until we receive a TDS_DONE
token w/ cancel flag set. I don't know why this doesn't work anymore but
the fact that there is an intermediate packet wouldn't matter, we'd know
we needed to continue to read as long as we hadn't seen a done.

Brian

On Sun, 1 Sep 2002, James K. Lowden wrote:

> On Sat, 31 Aug 2002 20:21:03 -0400 (EDT), "lbayuk AT mindspring.com"
> <lbayuk AT mindspring.com> wrote:
>
> > The trouble seems to start with PHP calling ct_cancel() after an error
> > reply. I think something is missing in the protocol here. With
> > FreeTDS-0.53, I used to get "Unknown marker 0!!" in Apache's error log
> > after each DBMS error reply. But client and server stayed in sync.
> > Later revisions to FreeTDS seemed to fix that - no more Unknown marker
> > messages, but now I realize it probably wasn't fixed, just masked.
> >
> > I think it is getting messed up in tds_process_cancel(). I added some
> > more tracing, and it thinks it is seeing a 0 byte (the same as FreeTDS
> > 0.53), but now it takes that as a Cancel and returns without getting the
> > DONE message. But the server isn't done, and still sends a DONE
> > message. I think that's what's going on, because the DONE message that
> > FreeTDS thinks belongs to the next query actually has the "cancelled"
> > flag bit set.
> >
> > I used a TCP socket tracing program to look more closely (because the
> > TDS dump file doesn't show this). I don't understand the reply from the
> > server to CANCEL. Here's the client sending CANCEL (type=06):
> > 06 01 00 08 00 00 00 00
> > Here's the server reply:
> > 0f 03 00 08 00 00 00 00
> > 04 01 00 11 00 00 00 00 fd 20 00 01 00 00 00 00 00
> > The second reply line is a Response (04), Result Set DONE (fd) with
> > Cancel bit (20). But what the heck is that first reply line?
> > tds_read_packet() is returning 0 when it reads that, because no data
> > follows the 8-byte header; then tds_process_cancel() takes that 0 as the
> > end of the cancel reply, leaving the real DONE+Cancelled message unread
> > until the next query.
>
> Thank you for the problem report, lbayuk.
>
> According to CVS tds_process_cancel() changed, just as you say, in
> revision 1.26 of token.c. It was part of the "tight loop" patch. Squish
> one bug, find another? OTOH, token.c has seen a lot of work; something
> else may be happening.
>
> That "0f" is a "TDS_BUF_NORMAL" response (p. 195 in the document below).
> The 0x03 after it is the status byte, indicating TDS_BUFSTAT_EOM (bit 0,
> last buffer in a response) and TDS_BUFSTAT_ATTNACK (bit 1,
> acknowledgment). That's the expected response to a cancel request.
>
> tds.h doesn't define a token for 0x0f, so I think our cancel protocol
> processing isn't interpreting it correctly.
>
> The real question, as far as I can tell, is not what the first response is
> (that looks fine according to their doc), but how to know to expect more
> incoming data on an "idle" link.
>
> I know almost nothing about the TDS protocol proper, so I'm not going to
> be very helpful in telling you what to do. In particular, I don't know
> how tds_process_cancel() can know that it's going to receive two (or
> more?) responses. According to the documentation, what you say you're
> seeing can't happen. I've attached the relevant part from page 20, in
> case you don't want to download the whole thing. HTH.
>
> Regards,
>
> --jkl
>
> Sybase's document says:
>
> <doc="http://www.SchemaMania.org/sybase/doc/pdf/tds_50_functional_specifi
> cation.pdf">
> 11. Cancel Protocol
>
> A cancel request is sent using a non-expedited TDS packet with the
> header type set to TDS_BUF_URGENT and the packet header status bit
> set to TDS_BUFSTAT_ATTN. The client will then read packets from the
> server until the cancel is acknowledged with a packet of header type
> TDS_BUF_NORMAL and the packet header status bit set to
> TDS_BUFSTAT_ATTNACK. The data, if any, in the packet with the
> TDS_BUFSTAT_ATTNACK bit set is discard. Once the client receives a
> packet with the header status bit TDS_BUFSTAT_ATTNACK set, the dialog
> state is returned to an idle state. The client may now issue another
> request.
>
> When a TDS_BUFSTAT_ATTN is sent by a client the TDS_BUFSTAT_EOM bit must
> also be set in the header status field. The TDS_BUFSTAT_ATTNACK returned
> by a server in response to a TDS_BUFSTAT_ATTN must have the
> TDS_BUFSTAT_EOM bit set at the end of the response. However, the
> TDS_BUFSTAT_ATTNACK can have a data length of 0 or greater. All data in
> the TDS_BUFSTAT_ATTNACK response can be safely discard by the client.
>
> Any dialog state information required by the sender of a TDS_BUFSTAT_ATTN
> is explictly requested by the sender after the TDS_BUFSTAT_ATTNACK has
> been received. The only state information currently required by a client
> is the state of all open cursors on the dialog. This state information is
> requested by the client by sending a TDS_CURINFO token with a cmd argument
> of TDS_CUR_CMD_INQUIRE and a cursor id of 0.
>
> Client Server
> -- In-band packet of
> type TDS_BUF_URGENT,
> status -- Stop current processing,
> TDS_BUFSTAT_ATTN | TDS_BUFSTAT_EOM not necessarily on a TDS token
> boundary.
> -- If packet not TDS_BUFSTAT_EOM,
> continue readinguntil
> TDS_BUFSTAT_EOM.
> <-- Return in-band packet of
> type TDS_BUF_NORMAL with
> -- Read and discard all packets status of TDS_BUFSTAT_ATTNACK.
> between sending of cancel Set TDS_BUFSTAT_EOM bit
> and receipt of TDS_BUFSTAT_ATTNACK in last packet.
> packet. At this point both
> ends are re-synchronized.
> -- Server now in idle state.
> -- If TDS_BUFSTAT_ATTNACK not also
> TDS_BUFSTAT_EOM, continue reading
> packetsuntil TDS_BUFSTAT_EOM.
>
> -- Dialog now in idle state.
> </doc>
>
> ---
> You are currently subscribed to freetds as: [camber AT ais.org]
> To unsubscribe, forward this message to $subst('Email.Unsub')
>
>





Archive powered by MHonArc 2.6.24.

Top of Page