drdaconnthread.java
来自「derby database source code.good for you.」· Java 代码 · 共 2,217 行 · 第 1/5 页
JAVA
2,217 行
/** * Parse manager levels * Instance variables * MGRLVL - repeatable, required * CODEPOINT * CCSIDMGR - CCSID Manager * CMNAPPC - LU 6.2 Conversational Communications Manager * CMNSYNCPT - SNA LU 6.2 SyncPoint Conversational Communications Manager * CMNTCPIP - TCP/IP Communication Manager * DICTIONARY - Dictionary * RDB - Relational Database * RSYNCMGR - Resynchronization Manager * SECMGR - Security Manager * SQLAM - SQL Application Manager * SUPERVISOR - Supervisor * SYNCPTMGR - Sync Point Manager * VALUE * * On the second appearance of this codepoint, it can only add managers * * @param time 1 for first time this is seen, 2 for subsequent ones * @exception DRDAProtocolException * */ private void parseMGRLVLLS(int time) throws DRDAProtocolException { int manager, managerLevel; int currentLevel; // set up vectors to keep track of manager information unknownManagers = new Vector(); knownManagers = new Vector(); errorManagers = new Vector(); errorManagersLevel = new Vector(); if (SanityManager.DEBUG) trace("Manager Levels"); while (reader.moreDdmData()) { manager = reader.readNetworkShort(); managerLevel = reader.readNetworkShort(); if (CodePoint.isKnownManager(manager)) { knownManagers.addElement(new Integer(manager)); //if the manager level hasn't been set, set it currentLevel = appRequester.getManagerLevel(manager); if (currentLevel == appRequester.MGR_LEVEL_UNKNOWN) appRequester.setManagerLevel(manager, managerLevel); else { //if the level is still the same we'll ignore it if (currentLevel != managerLevel) { //keep a list of conflicting managers errorManagers.addElement(new Integer(manager)); errorManagersLevel.addElement(new Integer (managerLevel)); } } } else unknownManagers.addElement(new Integer(manager)); if (SanityManager.DEBUG) trace("Manager = " + java.lang.Integer.toHexString(manager) + " ManagerLevel " + managerLevel); } sqlamLevel = appRequester.getManagerLevel(CodePoint.SQLAM); // did we have any errors if (errorManagers.size() > 0) { Object [] oa = new Object[errorManagers.size()*2]; int j = 0; for (int i = 0; i < errorManagers.size(); i++) { oa[j++] = errorManagers.elementAt(i); oa[j++] = errorManagersLevel.elementAt(i); } throw new DRDAProtocolException(DRDAProtocolException.DRDA_Proto_MGRLVLRM, this, 0, 0, oa); } } /** * Write reply to EXCSAT command * Instance Variables * EXTNAM - External Name (optional) * MGRLVLLS - Manager Level List (optional) * SRVCLSNM - Server Class Name (optional) - used by JCC * SRVNAM - Server Name (optional) * SRVRLSLV - Server Product Release Level (optional) * * @exception DRDAProtocolException */ private void writeEXCSATRD() throws DRDAProtocolException { writer.createDssReply(); writer.startDdm(CodePoint.EXCSATRD); writer.writeScalarString(CodePoint.EXTNAM, server.att_extnam); //only reply with manager levels if we got sent some if (knownManagers != null && knownManagers.size() > 0) writeMGRLEVELS(); writer.writeScalarString(CodePoint.SRVCLSNM, server.att_srvclsnm); writer.writeScalarString(CodePoint.SRVNAM, server.ATT_SRVNAM); writer.writeScalarString(CodePoint.SRVRLSLV, server.att_srvrlslv); writer.endDdmAndDss(); } /** * Write manager levels * The target server must not provide information for any target * managers unless the source explicitly requests it. * For each manager class, if the target server's support level * is greater than or equal to the source server's level, then the source * server's level is returned for that class if the target server can operate * at the source's level; otherwise a level 0 is returned. If the target * server's support level is less than the source server's level, the * target server's level is returned for that class. If the target server * does not recognize the code point of a manager class or does not support * that class, it returns a level of 0. The target server then waits * for the next command or for the source server to terminate communications. * When the source server receives EXCSATRD, it must compare each of the entries * in the mgrlvlls parameter it received to the corresponding entries in the mgrlvlls * parameter it sent. If any level mismatches, the source server must decide * whether it can use or adjust to the lower level of target support for that manager * class. There are no architectural criteria for making this decision. * The source server can terminate communications or continue at the target * servers level of support. It can also attempt to use whatever * commands its user requests while receiving error reply messages for real * functional mismatches. * The manager levels the source server specifies or the target server * returns must be compatible with the manager-level dependencies of the specified * manangers. Incompatible manager levels cannot be specified. * Instance variables * MGRLVL - repeatable, required * CODEPOINT * CCSIDMGR - CCSID Manager * CMNAPPC - LU 6.2 Conversational Communications Manager * CMNSYNCPT - SNA LU 6.2 SyncPoint Conversational Communications Manager * CMNTCPIP - TCP/IP Communication Manager * DICTIONARY - Dictionary * RDB - Relational Database * RSYNCMGR - Resynchronization Manager * SECMGR - Security Manager * SQLAM - SQL Application Manager * SUPERVISOR - Supervisor * SYNCPTMGR - Sync Point Manager * XAMGR - XA manager * VALUE */ private void writeMGRLEVELS() throws DRDAProtocolException { int manager; int appLevel; int serverLevel; writer.startDdm(CodePoint.MGRLVLLS); for (int i = 0; i < knownManagers.size(); i++) { manager = ((Integer)knownManagers.elementAt(i)).intValue(); appLevel = appRequester.getManagerLevel(manager); serverLevel = server.getManagerLevel(manager); if (serverLevel >= appLevel) { //Note appLevel has already been set to 0 if we can't support //the original app Level writer.writeCodePoint4Bytes(manager, appLevel); } else { writer.writeCodePoint4Bytes(manager, serverLevel); // reset application manager level to server level appRequester.setManagerLevel(manager, serverLevel); } } // write 0 for all unknown managers for (int i = 0; i < unknownManagers.size(); i++) { manager = ((Integer)unknownManagers.elementAt(i)).intValue(); writer.writeCodePoint4Bytes(manager, 0); } writer.endDdm(); } /** * Parse Access Security * * If the target server supports the SECMEC requested by the application requester * then a single value is returned and it is identical to the SECMEC value * in the ACCSEC command. If the target server does not support the SECMEC * requested, then one or more values are returned and the application requester * must choose one of these values for the security mechanism. * We currently support * - user id and password (default for JCC) * - encrypted user id and password * * Instance variables * SECMGRNM - security manager name - optional * SECMEC - security mechanism - required * RDBNAM - relational database name - optional * SECTKN - security token - optional, (required if sec mech. needs it) * * @return security check code - 0 if everything O.K. */ private int parseACCSEC() throws DRDAProtocolException { int securityCheckCode = 0; int securityMechanism = 0; byte [] publicKeyIn = null; reader.markCollection(); int codePoint = reader.getCodePoint(); while (codePoint != -1) { switch(codePoint) { //optional case CodePoint.SECMGRNM: // this is defined to be 0 length if (reader.getDdmLength() != 0) badObjectLength(CodePoint.SECMGRNM); break; //required case CodePoint.SECMEC: checkLength(CodePoint.SECMEC, 2); securityMechanism = reader.readNetworkShort(); if (SanityManager.DEBUG) trace("Security mechanism = " + securityMechanism); // for plain text userid,password USRIDPWD, and USRIDONL // no need of decryptionManager if (securityMechanism != CodePoint.SECMEC_USRIDPWD && securityMechanism != CodePoint.SECMEC_USRIDONL) { //this is the only other one we understand if (securityMechanism != CodePoint.SECMEC_EUSRIDPWD) securityCheckCode = CodePoint.SECCHKCD_NOTSUPPORTED; else { try { if (decryptionManager == null) decryptionManager = new DecryptionManager(); myPublicKey = decryptionManager.obtainPublicKey(); } catch (SQLException e) { println2Log(null, session.drdaID, e.getMessage()); // Local security service non-retryable error. securityCheckCode = CodePoint.SECCHKCD_0A; } } } break; //optional (currently required for Cloudscape - may need to revisit) case CodePoint.RDBNAM: String dbname = parseRDBNAM(); Database d = session.getDatabase(dbname); if (d == null) addDatabase(dbname); else database = d; break; //optional - depending on security Mechanism case CodePoint.SECTKN: publicKeyIn = reader.readBytes(); break; default: invalidCodePoint(codePoint); } codePoint = reader.getCodePoint(); } // check for required CodePoint's if (securityMechanism == 0) missingCodePoint(CodePoint.SECMEC); // RESOLVE - when we look further into security we might want to // handle this part of the protocol at the session level without // requiring a database for when authentication is used but there // is no database level security if (database == null) missingCodePoint(CodePoint.RDBNAM); database.securityMechanism = securityMechanism; database.publicKeyIn = publicKeyIn; // need security token if (securityCheckCode == 0 && database.securityMechanism == CodePoint.SECMEC_EUSRIDPWD && database.publicKeyIn == null) securityCheckCode = CodePoint.SECCHKCD_SECTKNMISSING_OR_INVALID; // shouldn't have security token if (securityCheckCode == 0 && (database.securityMechanism == CodePoint.SECMEC_USRIDPWD || database.securityMechanism == CodePoint.SECMEC_USRIDONL) && database.publicKeyIn != null) securityCheckCode = CodePoint.SECCHKCD_SECTKNMISSING_OR_INVALID; if (SanityManager.DEBUG) trace("** ACCSECRD securityCheckCode is: "+securityCheckCode); // If the security check was successful set the session state to // security accesseed. Otherwise go back to attributes exchanged so we // require another ACCSEC if (securityCheckCode == 0) session.setState(session.SECACC); else session.setState(session.ATTEXC); return securityCheckCode; } /** * Parse OPNQRY * Instance Variables * RDBNAM - relational database name - optional * PKGNAMCSN - RDB Package Name, Consistency Token and Section Number - required * QRYBLKSZ - Query Block Size - required * QRYBLKCTL - Query Block Protocol Control - optional * MAXBLKEXT - Maximum Number of Extra Blocks - optional - default value 0 * OUTOVROPT - Output Override Option * QRYROWSET - Query Rowset Size - optional - level 7 * MONITOR - Monitor events - optional. * * @return RDB Package Name, Consistency Token, and Section Number * @exception DRDAProtocolException */ private Pkgnamcsn parseOPNQRY() throws DRDAProtocolException, SQLException { Pkgnamcsn pkgnamcsn = null; boolean gotQryblksz = false; int blksize = 0; int qryblkctl = CodePoint.QRYBLKCTL_DEFAULT; int maxblkext = CodePoint.MAXBLKEXT_DEFAULT; int qryrowset = CodePoint.QRYROWSET_DEFAULT; int qryclsimp = DRDAResultSet.QRYCLSIMP_DEFAULT; int outovropt = CodePoint.OUTOVRFRS; reader.markCollection(); int codePoint = reader.getCodePoint(); while (codePoint != -1) { switch(codePoint) { //optional case CodePoint.RDBNAM: setDatabase(CodePoint.OPNQRY); break; //required case CodePoint.PKGNAMCSN: pkgnamcsn = parsePKGNAMCSN(); break; //required case CodePoint.QRYBLKSZ: blksize = parseQRYBLKSZ(); gotQryblksz = true; break; //optional case CodePoint.QRYBLKCTL: qryblkctl = reader.readNetworkShort(); //The only type of query block control we can specify here //is forced fixed row if (qryblkctl != CodePoint.FRCFIXROW) invalidCodePoint(qryblkctl); if (SanityManager.DEBUG) trace("!!qryblkctl = "+Integer.toHexString(qryblkctl)); gotQryblksz = true; break; //optional case CodePoint.MAXBLKEXT: maxblkext = reader.readSignedNetworkShort(); if (SanityManager.DEBUG) trace("maxblkext = "+maxblkext); break; // optional case CodePoint.OUTOVROPT: outovropt = parseOUTOVROPT(); break; //optional case CodePoint.QRYROWSET: //Note minimum for OPNQRY is 0 qryrowset = parseQRYROWSET(0); break; case CodePoint.QRYCLSIMP: // Implicitly close non-scrollable cursor qryclsimp = parseQRYCLSIMP(); break; case CodePoint.QRYCLSRLS: // Ignore release of read locks. Nothing we can do here parseQRYCLSRLS(); break; case CodePoint.QRYOPTVAL: // optimize for n rows. Not supported by cloudscape(ignore) parseQRYOPTVAL(); break; // optional case CodePoint.MONITOR: parseMONITOR(); break; default: invalidCodePoint(codePoint); } codePoint = reader.getCodePoint(); } // check for required variables if (pkgnamcsn == null) missingCodePoint(CodePoint.PKGNAMCSN); if (!gotQryblksz) missingCodePoint(CodePoint.QRYBLKSZ); // get the statement we are opening DRDAStatement stmt = database.getDRDAStatement(pkgnamcsn); if (stmt == null) { //XXX should really throw a SQL Exception here invalidValue(CodePoint.PKGNAMCSN); } // check that this statement is not already open // commenting this check out for now // it turns out that JCC doesn't send a close if executeQuery is // done again without closing the previous result set // this check can't be done since the second executeQuery should work //if (stmt.state != DRDAStatement.NOT_OPENED) //{ // writeQRYPOPRM(); // pkgnamcsn = null; //} //else //{ stmt.setOPNQRYOptions(blksize,qryblkctl,maxblkext,outovropt, qryrowset, qryclsimp); //} // read the command objects // for ps with parameter if (reader.isChainedWithSameID()) { if (SanityManager.DEBUG) trace("&&&&&& parsing SQLDTA"); parseOPNQRYobjects(stmt); } return pkgnamcsn; } /** * Parse OPNQRY objects * Objects * TYPDEFNAM - Data type definition name - optional * TYPDEFOVR - Type defintion overrides - optional * SQLDTA- SQL Program Variable Data - optional *
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?