Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Send op_disconnect [DNET275] #286

Closed
firebird-automations opened this issue Sep 28, 2009 · 14 comments
Closed

Send op_disconnect [DNET275] #286

firebird-automations opened this issue Sep 28, 2009 · 14 comments

Comments

@firebird-automations
Copy link

Submitted by: @dyemanov

Is related to CORE2462

Jiri,

As far as I remember, the .NET provider doesn't send op_disconnect to the server either. Could you please check whether it's true and fix the code appropriately?

This is indirectly related to CORE2462 where both main and event ports are disconnected only forcibly via the socket shutdown and the server sometimes has problems with that.

Dmitry

-------- Original Message --------
Subject: [Firebird-checkins] CVS:
Date: Tue, 29 Sep 2009 06:31:54 +0000 (UTC)
From: mailto:rrokytskyy@users.sourceforge.net ("Roman Rokytskyy")
Organization: Firebird and InterBase Community Site
To: mailto:firebird-checkins@lists.sourceforge.net
Newsgroups: sourceforge.firebird-checkins

Update of
/cvsroot/firebird/client-java/src/main/org/firebirdsql/gds/impl/wire
In directory
http://fdv4jf1.ch3.sourceforge.com:/tmp/cvs-serv13506/src/main/org/firebirdsql/gds/impl/wire

Modified Files:
AbstractJavaGDSImpl.java
Log Message:
Jaybird was not sending op_disconnect on isc_database_detach and isc_service_detach and there was no op_connect on isc_service_attach

Index: AbstractJavaGDSImpl.java

RCS file:
/cvsroot/firebird/client-java/src/main/org/firebirdsql/gds/impl/wire/AbstractJavaGDSImpl.java,v
retrieving revision 1.23
retrieving revision 1.24
diff -b -U3 -r1.23 -r1.24
--- AbstractJavaGDSImpl.java 18 Sep 2009 08:12:25 -0000 1.23
+++ AbstractJavaGDSImpl.java 29 Sep 2009 06:58:33 -0000 1.24
@@ -643,6 +643,7 @@
log.debug("op_detach ");
db.out.writeInt(op_detach);
db.out.writeInt(db.getRdb_id());
+ db.out.writeInt(op_disconnect);
db.out.flush();
if (debug)
log.debug("sent");
@@ -1170,12 +1171,12 @@
stmt.notifyOpenResultSet();
if (debug)
log.debug("sent");
- int op = nextOperation(db);
+ int op = nextOperation(http://db.in);
if (op == op_sql_response) {
// this would be an Execute procedure
stmt.ensureCapacity(1);
receiveSqlResponse(db, out_xsqlda, stmt);
- op = nextOperation(db);
+ op = nextOperation(http://db.in);
stmt.setAllRowsFetched(true);
stmt.setSingletonResult(true);
} else {
@@ -1283,10 +1284,10 @@
if (debug)
log.debug("sent");

- int op = nextOperation(db);
+ int op = nextOperation(http://db.in);
if (op == op_sql_response) {
receiveSqlResponse(db, out_xsqlda, null);
- op = nextOperation(db);
+ op = nextOperation(http://db.in);
}
receiveResponse(db, op);
} catch (IOException ex) {
@@ -1331,7 +1332,7 @@
if (debug)
log.debug("sent");

- int op = nextOperation(db);
+ int op = nextOperation(http://db.in);
stmt.notifyOpenResultSet();
if (op == op_fetch_response) {

@@ -1345,7 +1346,7 @@
if (sqldata_messages > 0 && sqldata_status == 0) {
in.readSQLData(xsqlda.ioLength, stmt);
do {
- op = nextOperation(db);
+ op = nextOperation(http://db.in);
if (op == op_response) {
receiveResponse(db, op);
continue;
@@ -1925,6 +1926,7 @@
protected void connect(isc_db_handle_impl db, DbAttachInfo dbai,
DatabaseParameterBuffer databaseParameterBuffer)
throws GDSException {
+
boolean debug = log != null && log.isDebugEnabled();

	int socketBufferSize = \-1;

@@ -1949,10 +1951,41 @@
try {
openSocket(db, dbai, debug, socketBufferSize);

+ XdrOutputStream out = db.out;
+ XdrInputStream in = http://db.in;
+ String fileName = dbai.getFileName();
+
+ int nextOperation = sendConnectPacket(out, in, fileName);
+
+ if (nextOperation == op_accept) {
+ db.setProtocol(in.readInt()); // Protocol version number
+ int arch = in.readInt(); // Architecture for protocol
+ int min = in.readInt(); // Minimum type
+ if (debug)
+ log.debug("received");
+ } else {
+ disconnect(db);
+ if (debug)
+ log.debug("not received");
+ throw new GDSException(ISCConstants.isc_connect_reject);
+ }
+ } catch (IOException ex) {
+ if (debug)
+ log.debug("IOException while trying to connect to db:", ex);
+ throw new GDSException(ISCConstants.isc_arg_gds,
+ ISCConstants.isc_network_error, dbai.getServer());
+ }
+ }
+
+ protected int sendConnectPacket(XdrOutputStream out, XdrInputStream in,
+ String fileName) throws IOException {
+
+ boolean debug = log != null && log.isDebugEnabled();
+
// Here we identify the user to the engine. This may or may not be
- // used
- // as login info to a database.
+ // used as login info to a database.
String user = System.getProperty("http://user.name");
+
if (debug)
log.debug("http://user.name: " + user);

@@ -1994,44 +2027,29 @@

		if \(debug\)
			log\.debug\("op\_connect "\);

- db.out.writeInt(op_connect);
- db.out.writeInt(op_attach);
- db.out.writeInt(2); // CONNECT_VERSION2
- db.out.writeInt(1); // arch_generic
+ out.writeInt(op_connect);
+ out.writeInt(op_attach);
+ out.writeInt(2); // CONNECT_VERSION2
+ out.writeInt(1); // arch_generic
// db.out.writeString(file_name); // p_cnct_file
- db.out.writeString(dbai.getFileName()); // p_cnct_file
- db.out.writeInt(1); // p_cnct_count
- db.out.writeBuffer(user_id); // p_cnct_user_id
-
- db.out.writeInt(10); // PROTOCOL_VERSION10
- db.out.writeInt(1); // arch_generic
- db.out.writeInt(2); // ptype_rpc
- db.out.writeInt(3); // ptype_batch_send
- db.out.writeInt(2);
- db.out.flush();
+ out.writeString(fileName); // p_cnct_file
+ out.writeInt(1); // p_cnct_count
+ out.writeBuffer(user_id); // p_cnct_user_id
+
+ out.writeInt(10); // PROTOCOL_VERSION10
+ out.writeInt(1); // arch_generic
+ out.writeInt(2); // ptype_rpc
+ out.writeInt(3); // ptype_batch_send
+ out.writeInt(2);
+ out.flush();
if (debug)
log.debug("sent");

		if \(debug\)
			log\.debug\("op\_accept "\);

- if (nextOperation(db) == op_accept) {
- db.setProtocol(db.in.readInt()); // Protocol version number
- int arch = db.in.readInt(); // Architecture for protocol
- int min = db.in.readInt(); // Minimum type
- if (debug)
- log.debug("received");
- } else {
- disconnect(db);
- if (debug)
- log.debug("not received");
- throw new GDSException(ISCConstants.isc_connect_reject);
- }
- } catch (IOException ex) {
- if (debug)
- log.debug("IOException while trying to connect to db:", ex);
- throw new GDSException(ISCConstants.isc_arg_gds,
- ISCConstants.isc_network_error, dbai.getServer());
- }
+
+ int nextOperation = nextOperation(in);
+ return nextOperation;
}

/\*\*

@@ -2115,7 +2133,7 @@
// when used directly
try {
if (op == -1)
- op = nextOperation(db);
+ op = nextOperation(http://db.in);
if (debug)
log.debug("op_response ");
if (op == op_response) {
@@ -2157,11 +2175,11 @@
}
}

- protected int nextOperation(isc_db_handle_impl db) throws IOException {
+ protected int nextOperation(XdrInputStream in) throws IOException {
boolean debug = log != null && log.isDebugEnabled();
int op = 0;
do {
- op = db.in.readInt();
+ op = in.readInt();
if (debug) {
if (op == op_dummy) {
log.debug("op_dummy received");
@@ -2704,7 +2722,7 @@
synchronized (svc) {
try {
try {
- svc.socket = new Socket(host, port);
+ svc.socket = getSocket(host, port);
svc.socket.setTcpNoDelay(true);

				// if \(socketBufferSize \!= \-1\) \{

@@ -2724,6 +2742,22 @@
svc.out = new XdrOutputStream(svc.socket.getOutputStream());
http://svc.in = new XdrInputStream(svc.socket.getInputStream());

+ int nextOperation = sendConnectPacket(svc.out, http://svc.in,
+serviceMgrStr);
+
+ if (nextOperation == op_accept) {
+ svc.in.readInt(); // Protocol version number
+ svc.in.readInt(); // Architecture for protocol
+ svc.in.readInt(); // Minimum type
+ if (debug)
+ log.debug("received");
+ } else {
+ svc.invalidate();
+ if (debug)
+ log.debug("not received");
+ throw new GDSException(ISCConstants.isc_connect_reject);
+ }
+
+
if (debug)
log.debug("op_service_attach ");
svc.out.writeInt(op_service_attach);
@@ -2761,7 +2795,7 @@
// when used directly
try {
if (op == -1)
- op = nextOperation(svc);
+ op = nextOperation(http://svc.in);
if (debug)
log.debug("op_response ");
if (op == op_response) {
@@ -2791,20 +2825,6 @@
}
}

- protected int nextOperation(isc_svc_handle_impl svc) throws IOException {
- boolean debug = log != null && log.isDebugEnabled();
- int op = 0;
- do {
- op = svc.in.readInt();
- if (debug) {
- if (op == op_dummy) {
- log.debug("op_dummy received");
- }
- }
- } while (op == op_dummy);
- return op;
- }
-
private void readStatusVector(isc_svc_handle_impl svc) throws GDSException {
boolean debug = log != null && log.isDebugEnabled();
try {
@@ -2907,6 +2927,7 @@
try {
svc.out.writeInt(op_service_detach);
svc.out.writeInt(svc.getHandle());
+ svc.out.writeInt(op_disconnect);
svc.out.flush();

			receiveResponse\(svc, \-1\);

@@ -3014,7 +3035,7 @@
db.out.writeInt(0);
db.out.flush();

- nextOperation(db);
+ nextOperation(http://db.in);

                  int auxHandle = db\.in\.readInt\(\);
                  // garbage

@@ -3145,7 +3166,7 @@
public void run(){
try {
while (running){
- int op = nextOperation(db);
+ int op = nextOperation(http://db.in);
switch (op){
case op_response:
receiveResponse(db, op);

Commits: 5f870fa a169afc 0b4ac9c

@firebird-automations
Copy link
Author

Modified by: @cincuranet

reporter: Jiri Cincura [ cincura_net ] => Dmitry Yemanov [ dimitr ]

@firebird-automations
Copy link
Author

Commented by: Oleg Matveyev (o_matveev)

How about send op_connect in testcase connect to Services API ?
Look comments in JDBC147

@firebird-automations
Copy link
Author

Modified by: @cincuranet

Link: This issue is related to CORE2462 [ CORE2462 ]

@firebird-automations
Copy link
Author

Commented by: @cincuranet

op_connect is sent in .NET provider correctly (according to what I see in FB sources).

@firebird-automations
Copy link
Author

Modified by: @cincuranet

status: Open [ 1 ] => Resolved [ 5 ]

resolution: Fixed [ 1 ]

Fix Version: 2.5.2 [ 10370 ]

@firebird-automations
Copy link
Author

Commented by: @dyemanov

Jiri, is there a v2.5.2 build to test the bugfix? If not, when might one expect it to be available?

@firebird-automations
Copy link
Author

Commented by: @cincuranet

It's available in weekly builds (http://netprovider.cincura.net).

@firebird-automations
Copy link
Author

Commented by: Dzirt (dzirt)

Version 2.6.0.0
On connect to non-existent database or with wrong login/password and not using connection pooling also need send codes op_detach and op_disconnect to server.

May be such patch:

Index: FbConnection.cs

--- FbConnection.cs (revision 52043)
+++ FbConnection.cs (working copy)
@@ -548,7 +548,16 @@
{
// Do not use Connection Pooling
this.innerConnection = new FbConnectionInternal(this.options, this);
- this.innerConnection.Connect();
+ try
+ {
+ this.innerConnection.Connect();
+ }
+ catch ( Exception )
+ {
+ this.innerConnection.Dispose();
+ this.innerConnection = null;
+ throw;
+ }
}

#⁠if (!NET_CF)

@firebird-automations
Copy link
Author

Commented by: Dzirt (dzirt)

This patch will be better:

Index: NETProvider/source/FirebirdSql/Data/Client/Managed/Version10/GdsDatabase.cs

--- NETProvider/source/FirebirdSql/Data/Client/Managed/Version10/GdsDatabase.cs (revision 52043)
+++ NETProvider/source/FirebirdSql/Data/Client/Managed/Version10/GdsDatabase.cs (working copy)
@@ -218,7 +218,19 @@

                 throw new IscException\(IscCodes\.isc\_net\_write\_err\);
             \}

+ catch ( IscException )
+ {
+ try
+ {
+ this.Detach();
+ }
+ catch ( Exception )
+ {
+ }

+ throw;
+ }
+
// Get server version
this.serverVersion = this.GetServerVersion();
}
@@ -255,8 +267,11 @@

             try
             \{

- this.Write(IscCodes.op_detach);
- this.Write(this.handle);
+ if ( this.handle != 0 )
+ {
+ this.Write( IscCodes.op_detach );
+ this.Write( this.handle );
+ }
this.Write(IscCodes.op_disconnect);
this.Flush();

It working with Pooling connection.

@firebird-automations
Copy link
Author

Commented by: @hvlad

Jiri,
could you comment patch by Dzirt ?
Looks ok at first glance.

@firebird-automations
Copy link
Author

Commented by: @cincuranet

Yes, looks OK. I'll deeply test it when implementing it.

@firebird-automations
Copy link
Author

Modified by: @cincuranet

status: Resolved [ 5 ] => Reopened [ 4 ]

resolution: Fixed [ 1 ] =>

@firebird-automations
Copy link
Author

Commented by: @cincuranet

rev.52685

@firebird-automations
Copy link
Author

Modified by: @cincuranet

status: Reopened [ 4 ] => Resolved [ 5 ]

resolution: Fixed [ 1 ]

Fix Version: 2.6.1 [ 10400 ]

Fix Version: 2.5.2 [ 10370 ] =>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants