Teoria Altamira Cics

-1- Casa abierta al tiempo es la frase que adoptada como lema institucional, expresa con profundo sentido la visión y

Views 201 Downloads 4 File size 4MB

Report DMCA / Copyright

DOWNLOAD FILE

Recommend stories

Citation preview

-1-

Casa abierta al tiempo es la frase que adoptada como lema institucional, expresa con profundo sentido la visión y el espíritu del proyecto académico de la Universidad Autónoma Metropolitana.

Convertida la frase el lema, apunta a los propósitos de la Universidad, que es Casa abierta al tiempo portador de sentido, posibilidad de saber y de diálogo.

-2-

SICOTIP: Sistema de comunicación para aplicaciones distribuidas (IG's) Cliente con comunicación a un MainFrame-Host. Resumen. El presente trabajo describe la propuesta de desarrollo del sistema de comunicación con sockets TCP-IP, entre un sistema distribuido y un equipo central (Mainframe). Se pretende que el proyecto a desarrollar pueda usarse en alguna empresa financiera, donde los sistemas pequeños tienen la necesidad de comunicarse con el equipo central o Mainframe. El tipo de sistema distribuido al cual nos enfocaremos, serán los llamados Call Center, así como los equipos automáticos de audio y respuesta los llamados IVR’s. Estos son usados para la atención telefónica de clientes de una empresa bancaria. Este tipo de sistemas que también tiene la necesidad de interactuar información con el equipo central, pero con la característica adicional que el típo de respuesta es un tema crítico, por lo que debe de ser rápido. El mainframe es el encargado de almacenar y centralizar toda la información de la cartera de clientes, en este tipo de empresas. Los equipos pequeños son los puntos donde se inician las solicitudes o requerimientos de operaciones bancarias o de servicio, que necesitan los clientes, y estos equipos retransmiten, informan o solicitan la petición al equipo central. Con el desarrollo, se pretende mejorar los tiempos de respuesta que se tiene en la comunicación entre los equipos pequeños (Call Centers e IVR’s). Donde se ha encontrado que muchas empresas bancarias manejan protocolos de comunicación más lentos y arcaicos. Un ejemplo muy claro es el uso de sesiones de SNA, en el cual se necesitaba crear un GUI la cual interactuaba a una sesión de SNA creando una emulación 3270 y internamente la aplicación GUI enviaba comandos a la sesión, tal como si se interaccionaba directamente sobre la emulación. Por lo que la GUI solo servio para visualizar la información de manera grafica, a este proceso se de denomina screen scraping. Este proceso de programación es muy lento y poco practico, debido a que se tiene realizar doble desarrollo, uno en la aplicación distribuida, así como su contraparte en el sistema central, para la creación de las pantallas que proporcionen la información. Se pretende que el desarrollo tenga como beneficios: disminuir considerablemente el tiempo que tarda una llamada que realizan los clientes al Banco, por lo que esto se traducirá en disminuir costos; aumento de la satisfacción del cliente, así como mejorar la atención del cliente; al contar con una comunicación mas rápida, da la oportunidad de ofrecerle mas productos y servicios a los clientes, los cuales usan el teléfono como medio de interacción con la empresa bancaria. Otro aspecto a considerar, es cuando el banco realiza la subcontratación de empresas (Outsourcing) de servicio de call centers, para que proporcionen parte del servicio de atención telefónica. Por lo que parte de la propuesta, en el sistema a construir, es que incluya un servidor Proxy. El cual servirá de entidad intermediaria de conexión entre alguna empresa extérna y la empresa bancaria, la cual contrata sus servicios. También, se considera que el sistema cuente con un módulo de encripción. Donde se propone que este módulo sea implementado en el estándar TDES, con el objetivo de encriptar los datos sensibles del mensaje que viaje entre la entidad externa y el banco, garantizando la

-3-

confidencialidad de la información del los clientes. Este módulo será configurable para poderse usar o no, en base a las necesidades del negocio. El sistema a desarrollar constara de dos componentes principales, el módulo cliente y el módulo servidor TCP-Proxy, los cuales están fundamentados en el manejo sockets TCP del protocolo TCPIP, garantizando un mejor enlace. La construcción del proyecto estará basado en C++, para garantizar mayor performance, así también nos permita poder tener la capacidad de realizar balanceo de cargas y tener la capacidad de transportabilidad en otras plataformas. Es entonces, que el módulo cliente permitirá el envío y recepción de mensajes en formato PS9 (protocolo lógico de información estándar para comunicación con el MainFrame), dando la posibilidad de usar o no encripción. La parte del modulo de servidor TCP-Proxy, tendrá como función la retransmisión de mensajes que reciba del modulo cliente, para las empresas externas de call center. Este componente, contará con la habilidad de ser multitarea (multithread), también se pretende que maneje la programación paralela y poder aprovechar la infraestructura del servidor o equipo que lo aloje, más si cuenta con procesadores multicore y/o multiprocesador.

-4-

Agradecimientos. Doy gracias a mis padres, por el apoyo incondicional que siempre me han dado y por que siempre creyeron en mí. Rodolfo Rosas Rico y Lucia Díaz Herrera. Mi sincero agradecimiento hacia mis hermanos: Maria, Sergio, Rodolfo y Verónica. Por su apoyo y motivación en mis estudios. Agradezco el gran apoyo del Maestro Omar Lucio Cabrera como mi asesor de proyecto. Mi reconocimiento y agradecimiento a la Universidad Autónoma Metropolitana, por ser

la

institución de excelencia para la formación de profesionistas e investigadores de excelencia y de la cual estoy orgulloso de haber egresado.

Dedicatoria; Dedico la presente obra a mi hermosa familia: mi esposa Celia, a mi nenita Lilian y al bebe que estamos esperando.

-5-

Contenido 1 Introducción. 2 Sistemas de Atención Telefónica. 2.1

Introducción.

2.2

Arquitectura base. PBX, IVR's y CTI.

3 MainFrame (Host). 3.1

Introducción.

3.2

Arquitectura sobre Host MainFrame.

3.3

Cics Bridge TCP-IP.

3.4

Protocolo PS-9.

4 Programación concurrente y paralela. 4.1

Introducción.

4.2

Programación Multihilo.

4.3

Modelos y herramientas de programación paralela.

4.4

Modelo y herramientas usados en el proyecto.

5 Criptografía. 5.1

Introducción

5.2

TDES y base 64, para el manejado en el proyecto.

6 Sistema de comunicación TCP-IP para aplicaciones cliente a Mainframe-Host (SICOTIP). 6.1

Requerimientos.

6.2

Análisis.

6.3

Diseño.

6.4

Construcción.

6.5

Conclusiones y resultados.

7 Referencias Anexo A. Código fuente.

-6-

SICOTIP: Sistema de comunicación para aplicaciones distribuidas (IG's) Cliente con comunicación a un MainFrame-Host. 1 Introducción.

El presente trabajo describe el desarrollo para la solución de comunicación de aplicaciones distribuidas de atención telefónica en la industria bancaria por sockets de TCP-IP, hacia el sistema central (Host OS-390). Esto en base la necesidad de contar de un medio de transmisión seguro de información y así como un medio mucho más rápido en tiempo de respuesta. Con el objeto de minimizar el tiempo de las llamadas que realiza los clientes al servicio de atención telefónica. Este servicio se proporciona con infraestructura de equipos de audio-respuesta automático IVR's y/o atención por asesores llamados Call Centers. Muchas empresas que ofrecen de estos servicios, para no invertir en infraestructura de este tipo, o tener que mejorarla constantemente. Recurren en la subcontratación de empresas externas (llamadas Outsourcing), las cuales dan el servicio de call centers. Con esto las empresas outsourcing pueden proporcionar parte o todo del servicio de atención telefónica a nombre del la empresa que contrata. Para que la empresa financiera pueda operar de manera adecuada con estas empresas se propone como parte de la solución el manejo de un Proxy (intermediario o sustituto), viéndose para el banco como un solo punto o nodo, el cual por razones de seguridad será solo uno punto a autorizado por el firewall del banco. Esta configuración permitirá que N cantidad de maquinas cliente se comuniquen con el Proxy y este retransmita el mensaje de manera segura al Banco y retorne la respuesta al nodo cliente que realizo la petición original. También, se contara con un modulo de encripción en TDES (estándar en muchas de estas empresas) para encriptar los datos sensibles del mensaje, el cual será configurable para usarse o no, en base a las necesidades del negocio. El sistema desarrollado consta de dos componentes principales, el modulo cliente y el modulo servidor TCP-Proxy basados en manejo sockets TCP de TCP-IP garantizando un mejor enlace. Todo el desarrollo se construyo en C++ para garantizar mayor performance, balanceo de cargas y transportabilidad en diferentes plataformas. Por lo que, el modulo cliente permitirá el envío-recepción de mensajes en formato PS9 (protocolo lógico de información estándar para comunicación con el MainFrame) con y sin encripción. La parte de módulo de servidor Proxy TCP, tendrá como función la de retransmitir los mensajes que reciba de la aplicación cliente que provengan de empresas externas que den el servicio de Call Center. En donde este componente tendrá la capacidad de ser multihilo (multithread), así como ampliando la capacidad de usar las ventajas de la programación en paralelo. Pudiendo explotar las ventajas de contar con un servidor que tenga una arquitectura de procesadores multicore y/o multiprocesador. Es entonces que el módulo cliente permitirá el envío-recepción de mensajes en formato PS9 (protocolo lógico de información estándar para comunicación con el MainFrame) con y sin encripción.

-7-

La parte del modulo de servidor TCP-Proxy, tendrá como función la retransmisión de mensajes que reciba del módulo cliente, para las empresas externas de call center. Este componente contara con la habilidad de ser multitarea (multithread), así como la posibilidad de usar programación paralela, teniendo la posibilidad de aprovechar la existencia de algún servidor con procesadores multicore y/o multiprocesador.

2 Sistemas de Atención Telefónica.

2.1

Introducción.

En cualquier institución financiera o Banco, es común que se cuente diferentes medios de interacción y atención de los clientes, por los cuales se ofrecen los servicios de la empresa. Estos medios pueden ser por ejemplo: el más común son las sucursales, el segundo mas común es por teléfono o denominado como atención telefónica (que proporcionan el servicio por medio de equipos automáticos llamados IVRs y los llamados Call Centers, los cuales dan la atención personalizada por medio de asesores telefónicos). También están los portales de servicio financiero, que es un sitio Web el cual se accesa vía Internet. Esta también los cajeros o ATMs, los cuales dan muy comúnmente el servicio de retiros de dinero y consulta de saldo, a un que mas recientemente ya dan servicio de depósitos de efectivo, entre otros mas servicios. El servicio bancario móvil, es un medio que tiene poco tiempo que ha surgido en México, el cual es por medio de acceso a la banca a través de un celular o un smartphone, por medio del cual se realizan las operaciones con el banco. Otro medio es el Kiosco, el cual principalmente sirven para realizar consultas de saldos y de sus últimos movimientos en su cuenta, estos dispositivos normalmente se les ubica en plazas comerciales. Estos son algunos de los más principales, pero existen cada vez mas una gama de medios de interacción del cliente (llámese persona física o moral). Un canal de comunicación, es una manera de denominar a cada una de las vías por las que la institución bancaria ofrece sus servicios financieros a sus clientes e incluso a sus no clientes. Para el presente trabajo, el sistema a desarrollar surgirá como una solución para la comunicación más rápida, para el canal de comunicación de atención telefónica. La atención telefónica de clientes y no clientes de algún Banco que requieran una ayuda y/o atención de cualquiera de los productos y/o servicios que ofrezca la institución financiera. El enfoque estará dado para que los servicio sean proporcionados a nivel nacional por un o varios Call Center internos y por un o varios Call Center Externos. Elementos que interviene en un servicio telefónico bancario:

Sistema CTI. Su función Integración del Programa Producto y desarrollos que permiten tener funciones de screen pop en los equipos desktop’s de los asesores telefónicos, permite realizar retornos a puntos exactos en los IVR’s, transferencia de llamadas con voz y datos entre alguno de los supuestos sites de un servicio telefónico de tipo bancario y otros mas sites de origen externo. Además permite a los asesores realizar las funciones telefónicas a través del CTI integrado a los aplicativos de servicio, esto permite a su vez poder tener un registro a detalle de todas las acciones que toman los asesores con los clientes, pudiendo entregar a la operación y al staff de un servicio telefónico de la empresa Bancaria los diversos tipos de reportes, que ayudan al monitoreo y el performance de la operación.

-8-

Flujo inicial de la llamada en coordinación de un CTI, con una infraestructura propuesta.

Interacción de un CTI en una propuesta de flujo de llamada

IVR Inicia ón con el Interacci Cliente y valida si es Y aplica Script Programado nueva Llamada . Convierte instrucciones del cliente En Transacciones hacia el HOST

6 1

3

AN I

COMPAÑIA TELEFONICA

PBX env Al IVR

2

La llamada llega a un Grupo de ón Priorizaci y Se transfiere al IVR

Cliente Marca

PBX informa a CTI Server De la llamada

ía llamada

7

SYMPOSIU M

HOST HOS

WA N

T

5

AN I

4

CTI Informa Inform a a la IVR Datos de llamada

CTI Server

Continuación del flujo de la llamada con coordinación de un CTI.

Conmutador(es

Interacción de un CTI en una propuesta de flujo de 9 9

PB

IVR Arma cadena con los datos del Cliente y ía solicitud de transferencia al CTI env

1 12

IV ´s Compañía que proporciona el servicio Telefónico

Informa al cliente tiempos de espera Solicita ón de confirmaci transferencia

1 14 Realiza 113

Cliente Marca 8 8

Cliente Solicita Transferencia con Un Agente

Transferencia

10 1

Symposiu ne as Di git al es

0 11 1 1

ACD Phon

CTI Server

Agente

HOS T

WA N

PBX Transfiere llamada Al ID Disponible

R ed Et he rn

R ed V í oz

13 1

3

CTI Recibe Sol. Transf. Asigna Prioridad Solicita a Symposiu Real Time tiempos en m de espera colas En ía tiempos al v IVR CTI Recibe ón de confirmaci En ía Datos de Transf. transferencia Al v PBX

ACD Phon e Agente

15 1 El5asesor recibe screen pop del Cliente y pasa info . A SDAT r SDAT

ACD Phon e Agente Servicio Tipo 1

16 1

6 Termina la llamada O transfiere a otro grupo (repite 10

ACD Phon

-15 )

Agente Servicio Tipo

Se guarda informaci en Llamada BD.

-9-

ón de la

17 1

7

Tabla CTI Tig045_CT I

I.

Interfaces del CTI con otros elementos de la atención telefónica.

I.I Interfase con aplicaciones de Interfaz Grafica. Esta interfase integra el CTI con la aplicación desktop de tipo GUI (Interfaz grafica de usuario, el cual puede ser desarrollada bajo Java, .Net, etc.), la cual utilizaran los asesores para atender todos los servicios que proporcionan en el centro de atención telefónico. Así como de realizar todas las funciones de telefonía desde la aplicación de CTI (transferencia, conferencias, llamadas de salida). I.II Interfase con Conmutador Estas interfases con el conmutador permiten al CTI hacer 4 funciones: a) DDR: Interfase entre CTI-PBX-IVR encargada de analizar las llamadas que solicitan un asesor en los IVR para transferirla de manera inteligente, según el tipo de cliente, servicio solicitado, antigüedad, zona regional, etc. para que se atienda con la prioridad y al grupo de asesores mejor capacitados según cada llamada. También es la encargada de pasar la información al los IVR para informarles a los clientes tiempos aproximados de atención b) RolingDnis: Interfase con diferentes conmutadores encargada de pasar las llamadas con voz y datos entre los diferentes conmutadores. c) CDN Abandono: Interfase contra el conmutador encargada de almacenar los datos telefónicos y así como de los datos de los clientes de las llamadas abandonadas, para su posterior marcación. d) CDN Monitor: Interfase contra el conmutador encargada de identificar y poner etiquetas a las llamadas que no pasan por IVR.

- 10 -

I.III Interfase con el sistema de grabación Esta interfase permite pasar los calificadores de login (clave de firmado del agente en el conmutador) al sistema de grabación para que se puedan realizar búsquedas de llamadas por este valor.

Interfases de componentes de un CTI.

CT I

Conmutador(e )



Interfase

Conmutador: Interfase

DD

Sistema de

Rollin

Grabacón

CDNMonito CDNColgad

Sistem de aGrabacion

Interfase CTI-Deskto

IV ’s R

GUI App Distrib.

2.2

Arquitectura base. PBX, IVR's y CTI.

Infraestructura Aplicación IVR de atención telefónica de algún banco.

En un centro telefónico propuesto se puede contar con más de 1600 puertos de IVR distribuidos en 3 sites con cobertura nacional. Bajo este esquema, se podrán recibir en promedio 5 millones de llamadas mensuales, de las cuales se transferirá sólo el 15% para su atención con algún asesor telefónico. Los IVRs serán manejados completamente en tonos. La comunicación al Host-MainFrame de una institución bancaria se propone sea a través de sockets de TCP/IP con el protocolo de formato de tramas PS-9. Los IVR’s contaran con licencias de TTS (Text to speech) para la conversión de texto a voz de los nick names que los clientes le asignan a cada una de sus cuentas de terceros para los traspasos y pagos en el servicio

- 11 -

avanzado. Se contara con una interacción con CTI a través de una dll para el manejo de sockets TCP de TCP/IP.

Configuración propuesta de 3 sites, instalados en tres ciudades principales, que darán servicio a todo el país.

Algunos de los servicios ofrecidos en el menú de autoservicio de atención telefónica que comúnmente se ofrecen en una institución financiera. Una aplicación de atención telefónica puede contar con servicios de números telefónicos, como por ejemplo: Números locales para cada ciudad principal del país, un servicio de 01-800 para el resto del país. Aunque existen diferentes números telefónicos para los segmentos de clientes, también la aplicación configura automáticamente las opciones de servicios y productos a ofrecer en los diferentes menús, los grupos de transferencia e incluso la voz de los mensajes en base a la información del cliente obtenida a partir de su plástico de acceso. El menú principal de acceso telefónico, puede constar de de tres opciones principalmente: de reporte por robo extravío, menú de transaccionalidad y menú de servicios:

- 12 -

• •



El menú de robo extravío transfiere las llamadas de forma directa con los asesores para el reporte de plásticos o cheques, que fueron extraviados o robados. El menú de transaccionalidad contiene la mayor parte de la aplicación, en él se pueden encontrar diferentes opciones las cuales se presentan en base a los productos financieros que tenga contratados el cliente. Contamos con alrededor de 100 transacciones diferentes, las cuales se utilizan a través de sockets de TCP/IP y tienen el formato PS9. Mensualmente se generan más de 10 millones de transacciones. El menú de servicios contiene la mayor parte de las opciones de transferencia. Previo a la transferencia se realizan validaciones en los productos de los clientes, en algunos casos se evita la transferencia informando al cliente, por ejemplo, el estatus de una aclaración, el envío de un plástico a domicilio, entre otros.

Configuración de ejemplo de un servicio telefónico bancario:

CENTRO1 576 PTS

81579111 27E1

CALL CENTER EXTERNO

IVR´ S

CIA TEL CALL CENTER EXTERNO

SYMPOSIUM SERVIDOR LINK

CTI

11E1 160CH/6E|

52262663 27E1 2E1

CIA TEL

5E1

3E1

562411XX

11E1

6E1 CIA TEL

CENTRO3

36690229

52262663 CONMUTADOR 2

CONMUTADOR 1

CENTRO2

9E1

13E1 CIA TEL

5E1

CIA TEL

2E1

SYMPOSIUM

SYMPOSIUM LINK

LINK

SYMPOSIUM

AGTS

LINK

250 AGTES

350 AGTES

SERVIDOR CTI

SERVIDOR IVR´S

172 PTS

SERVIDOR

CTI IVR´S

500 PTS

- 13 -

AGTS

CTI

IVR´S

355 PTS

3 MainFrame (Host).

3.1

Introducción.

Un mainframe es una computadora grande, con mucha capacidad, la cual es utilizada principalmente en empresas que necesitan procesar gran cantidad de datos y/o soportar gran cantidad de usuarios, muy común en la industria bancaria. Un mainframe puede funcionar durante muchos años sin problemas, ni interrupciones o incluso puede repararse mientras esta funcionando. También puede simular el funcionamiento de cientos de computadoras personales (terminadores virtuales) dentro de una empresa. Un mainframe no es lo mismo que una supercomputadora. Un mainframe es un repositorio de central de datos o un Hob, en una corporación con procesamiento central de datos. Este esta enlazado con los usuarios que cuentan con dispositivos con menos poder, tales como terminales, estaciones de trabajo o equipos de escritorio. La presencia de un mainframe frecuentemente implica una forma centralizada de computación, que es lo opuesto a una configuración de computación distribuida. Los equipos pequeños distribuidos, han estado creciendo enormemente, tal es el caso que la brecha de distinción entre estos y un mainframe es cada vez más confusa. Considerado esto, el nuevo enfoque de los mainframe, es ahora basado en su interacción en combinación de redes de pequeños servidores (sistemas distribuidos) en una infinidad de configuraciones, en base a las necesidades de las empresas. Los nuevos mainframes, deben de contar con una flexibilidad y evolución natural, la cual subraya la habilidad que tengan estos de reconfigurarse dinámicamente en aspectos de hardware y/o software (considerando procesamiento, memoria, disponibilidad de conexiones de dispositivos), esto mientras las aplicaciones continúan ejecutándose simultánea o paralelamente. El sistema operativo z/OS, es el S.O. usado principalmente en un mainframe. El sistema z/OS que se instala en un mainframe, esta diseñado para ofrecer un estable, seguro, y una continua disponibilidad de ambiente de aplicaciones en ejecución. Hoy en día, el z/OS es el resultado de décadas de avances tecnológicos, el cual fue evolucionando de ser un S.O. que solo podía ejecutar un simple programa a la vez, a un S.O. que puede manejar muchos de miles de programas a la vez y a su vez, proporcionar una interactiva concurrencia de usuarios. El Cics, definido por Costumer Information Control System. Es un subsistema de procesamiento transaccional de propósito general, enfocado principalmente para el z/OS. Donde el Cics provee de servicios que pueden ser ejecutados en una aplicación en línea (en línea significa, que el sistema proporciona una interacción y respuesta inmediata con el usuario), en base al requerimiento del usuario. Esto permite a muchos usuarios puedan realizar solicitudes de requerimientos al mismos tiempo. Se cuenta con el enfoque interno de que se puede ejecutar la misma aplicación, usando los mismos archivos y programas (denominado código reentrante). El Cics permite manejar los recursos compartidos, así como la integridad de los datos y priorización de ejecución, proporcionando una rápida respuesta. También autoriza a los usuarios, alojar los recursos (almacenamiento real y ciclos de ejecución), así como, dar pasa a los requerimientos de base de datos, por la aplicación, con el apropiado manejador de base de datos (tal como DB2).

- 14 -

Nosotros podemos decir que Cics actúa como el z/OS y realiza muchas de las mismas operaciones que el z/OS sistema operativo. Una aplicación Cics, es una colección de programas relacionados, los cuales juntos realizan una operación de negocio. Unos ejemplos pueden ser, el procesamiento de una solicitud de viaje o la preparación de una nómina de una empresa. Las aplicaciones de Cics, son ejecutadas bajo el control de Cics, usando servicios de Cics y sus interfaces de acceso a programas y de archivos. Las transacciones de cics son normalmente realizadas por ejecución de un requerimiento de transacción. La transacción ejecutada consiste en con correr una o mas programas de aplicación que implementan la función requerida.

3.2

Arquitectura ASTA (Altamira).

La Arquitectura ALTAMIRA es un sistema altamente parametrizado montado sobre Cics. En esta arquitectura es posible definir las entidades de trabajo, sus entornos y las características necesarias para el funcionamiento de tipo on-line, así como del procesamiento en batch. Una de las utilidades del Sistema de Arquitectura es la gestión de la paginación de los listados por pantalla (scroll a izquierda, derecha, arriba, abajo) de manera transparente a las aplicaciones, de tal manera que se simplifica notablemente el diseño y codificación de las transacciones de listado. Una convención que se tiene entre las diferentes aplicaciones, es que se comunicaran o se “hablarán” con la Arquitectura, fundamentalmente a través del área de comunicación CAA (un área de memoria estándar).

3.3

Cics Bridge TCP-IP.

El IBM CICS BRIDGE, es un conjunto de programas que forman parte de la interfase CICS Sockets y que son instalados conjuntamente con los programas dedicados a tal fin en el CSD de la región CICS. El objetivo del CICSBRIDGE es permitir que una aplicación transaccional síncrona distribuida pueda conseguir la ejecución de un programa residente en una región CICS OS/390 y obtener una respuesta mediante el uso de MQ, Sockets, etc. sin necesidad de que el programa CICS tenga que ser modificado para soportar dicha comunicación. Debido a las necesidades que se requieren en un banco determinado, es necesaria la implementación de una versión modificada de la versión original del Cics Bridge de IBM. En donde a continuación se menciona una versión propuesta que se puede usar en una empresa bancaria. A diferencia del monitor de IBM (Transacción CSKL), la versión propuesta está orientada al aprovechamiento de las facilidades transaccionales sobre CICSPLEX, al distribuir la carga transaccional en los AORes, evitando la concentración de transacciones en el TOR y evitando afinidades, y adicionando facilidades de sesiones y validaciones en RACF.

- 15 -

Componentes de una aplicación donde participa cicsbridge.

Diagrama de Flujo Cics Bridge TCP/IP que puede ser usado en un MainFrame. QGPARTC P

Aplicativo TCP/ IP Servi ces

CICS Sock ets API

START

QPTP

START USERID GENERICO

QG1CSP

QTxx

START USERID GENERICO

QG1CSER TCP/ IP Servi ces

TCP/ IP Serv

XYZ WXCTL

YMQ T

QOxx

LINK TRANSID

DFHMIR S

CICS TOR

QG1CS BP2

A R Q U I T E LINK C T U R A

A P L I C A T I V O S

CICS AOR

En un escenario aplicativo donde participa CICS Bridge pueden identificarse: 1) UN COMPONENTE CLIENTE. Es el que posee la información que debe ser procesada. Al usar CICS BRIDGE, necesariamente se considera un componente transaccional, es decir que entregará un mensaje y quedará en espera de la respuesta durante un tiempo preestablecido. El Cliente será en muchos de los casos un Distribuido (NT, UNIX, etc.). Se debe tener en cuenta que el mensaje que envíen debe estar en formato PS-9. 2) UN COMPONENTE SERVIDOR. Es el que puede llamar o efectuar un proceso sobre la información contenida en el mensaje que el cliente envía. Este componente es ejecutado por CICS BRIDGE usando el comando LINK, por lo que el contenido del mensaje es recibido en COMMAREA, siendo luego reemplazado por la respuesta o resultado del proceso. 3) CICS BRIDGE. Son los componentes ARRANQUE, MONITOR, PROCESADOR y SALIDA los que conforman el modelo de CICS Bridge. El ARRANQUE ejecuta la(s) Transacción(es) MONITOR(es), que son las encargadas de recibir mensajes en cualquier momento, tomarlos y mandarlos a procesar, el PROCESADOR identifica el mensaje y enviará hacia la arquitectura ASTA a ejecutar la transacción requerida, al regreso de la arquitectura el procesador envía la respuesta al componente de SALIDA que es el que restablece la comunicación con el distribuido y entrega la respuesta.

- 16 -

ARRANQUE CICS BRIDGE TCP. El arranque del CICS Bridge TCP se da mediante la ejecución de una transacción llamada de arranque QPTP ligada al programa QG1CSPTP, que su ejecución puede estar incluida al inicio el CICS TOR ó se puede ejecutar directamente dentro CICS con un usuario que tenga la autoridad respectiva. Esta transacción de arranque tiene por objetivo leer el archivo de parámetros del Cicsbridge TCP, y realizar un START a cada una de las transacciones monitoras que estén incluidas para el Cics en donde se esta ejecutando la transacción de arranque. Los parámetros para cada aplicación se envían como commarea de la transacción monitora ejecutada. Si en algún momento la transacción monitora tiene una terminación anormal (abend), antes de terminar su ejecución realizará un START con delay a la transacción se arranque con los datos de IP y puerto en donde estaba trabajando, para volver a arrancar el monitor. MONITOR DE CICS BRIDGE TCP. La transacción monitor de Cics bridge TCP se ejecuta en el Cics TOR de comunicaciones que incluya el CICS Sockets API. Una vez arrancada esta transacción estará monitoreando lo que fluya en el puerto de la IP con la cual se haya conectado. Cuando reciba un mensaje lo tomará, lo valida de acuerdo a los parámetros de arranque y en caso de ser aceptado realizará un START a la transacción llamada procesadora para atender el requerimiento, en caso contrario se regresará el código de error correspondiente. Si esta transacción tiene una terminación anormal (ABEND), antes de terminar realizará un START a la transacción de arranque con un delay de 60 segundos, con la IP y puerto enviado para que vuelva a levantar este monitor.

- 17 -

3.4

Protocolo PS-9.

El protocolo de comunicación entre el distribuido y el host, esta dado por el Cics bridge TCP debido a su desarrollo, aunque tiene un parámetro de protocolo que puede ser útil en caso de no querer utilizar el protocolo definido. Teniendo en cuenta que es un sistema de comunicaciones de un cliente ya sea un distribuido o un host hacia el equipo host de BBVA, atendiendo requerimientos principalmente de aplicaciones que se encuentran bajo la arquitectura Altamira, el flujo comienza en con el cliente. Antes de comenzar a describir el protocolo definiremos algunos de los formatos en los cuales se enviara la información. Α) MESSAGE DESCRIPTOR DE TCP. Formato de información de 160 posiciones fijas, en el cual se incluyen parámetros y datos propios de la aplicación y del operador, este formato tendrá que ser enviado siempre. Los campos contenidos en este formato son: Tipo

Descripción del Campo

Valor Default ó posibles

TAG DE INICIO DEL MESSAGE DESCRIPTOR

X(04)

LA VERSION DEL DISTRIBUIDO

X(05) 1.0.0

LONGITUD MAXIMA DEL MENSAJE PS9

9(05) 32584

IDENTIFICACION DEL MENSAJE ENVIADO

X(24)

Valor que hace msg único

TIEMPO PARA MONITOREO EN SEG. (WAITINTERVAL)

9(05) 00600

REQUERIMIENTO SOLICITADO de MD

TIPO DE VALIDACION DEL USUARIO

X(04) **** , LOGN, LOGF, VERY, LRSS, CHPW X(08) USERGENE, USERRACF, USER3270, USERDGPO X(04) **** ó RACF

CORRESPONDE AL USERID FINAL

X(08) USERID de 8 Posiciones

CORRESPONDE AL USERID DE GRUPO

X(08) Usuario de grupo si es el caso

PASSWORD ENCRIPTADA (BASE 64)

X(12) Password encriptada Base 64

PASSWORD NUEVA ENCRIPTADA (BASE 64)

X(12) Nva Password encriptada B64

TIPO DE USUARIO

NUMERO DE SESION

9(08) 00000000 ó Número de sesión

FECHA DE ENVIO

X(10) AAAA-MM-DD

HORA DE ENVIO

X(08) HH:MM:SS

DISPONIBLE

X(30) Espacios

TAG DE FIN DEL MESSAGE DESCRIPTOR

X(05)

Los siguientes formatos son propios del PS-9 Protocolo Información. Β) INPUT HEADER PS9. Header del Formato PS9 de 65 posiciones fijas. Este será inmediato al message descriptor de TCP. Tipo

Descripción del Campo

Valor Default ó posibles

TAG DE INICIO DEL INPUT HEADER

X(04)

CODIGO DEL PROTOCOLO DE INFORMACION

X(02) 26 para formato PS9

- 18 -

NÚMERO DE SECUENCIA

X(08) Terminal lógico alfanumérico X(08) Terminal alfanumérico contable X(08) User-id que envía la información X(08) Número de secuencia

CODIGO DE LA TRANSACCION

X(08) Transacción

OPCIÓN

9(02)

LONGITUD TOTAL DEL MENSAJE PS9

9(05)

INDICADOR DE COMMIT EN ALTAMIRA

9(01)

TIPO DE MENSAJE

9(01)

TIPO DE PROCESO

X(01)

CANAL

X(02) Canal de la aplicación

INDICADOR DE PREFORMATEO

X(01) ‘Y’ Formateo ‘N’ Sin Formateo X(01) Alfanumérico indicador el lenguaje X(05)

TERMINAL LOGICO TERMINAL CONTABLE USUARIO

LENGUAJE TAG DE FIN DEL INPUT HEADER

Intro=‘00’,F1=‘01’,F2=‘02’ ... Longitud PS9 desde a

‘0’ Sin commit ó ‘1’ con commit 1- New Request, 2- Authorization, 3- Conversation Scroll Info., 5- Conversation Continuation, 6- Authorization in a conversation ‘O’ On-line ‘F’ Off-line

Χ) INPUT MESSAGE. Este es el formato del mensaje que dependiendo del tipo de mensaje descrito en el Input Header y dependiendo de la transacción enviada será de formato y longitud variable. El formato más común que se utilizará bajo Cics bridge será el siguiente. Para mayor información sobre otro formato consultar el documento información del protocolo PS-9. Tipo

Descripción del Campo

Valor Default ó posibles X(04) 9(04) Longitud del COPY X(01) ‘C’ si es COPY ó ‘B’ Si es BMS X(---) Datos del copy X(05)

TAG DE INICIO DEL INPUT MESSAGE LONGITUD DEL COPY TIPO DEL COPY COPY TAG DE FIN DEL INPUT MESSAGE

El programa QG1CMTCP monitor bajo Sockets, una vez realizada la conexión a la IP y puerto correspondiente mediante API’s de Sockets, empieza por validar los tres formatos. Dependiendo del requerimiento del cliente es como se procesara la información.

- 19 -

a) Cuando parámetro de host TIPOREQUER es el valor default (espacios ó ****), nos indica que el cliente no requiere de sesiones de Cics bridge. Por lo que por cada petición del cliente tiene que enviar la siguiente secuencia de formato:





1. El programa leerá todo lo que el cliente envíe y primeramente tomara la parte de el message descriptor TCP checando los tags de este formato en la posición correspondiente, también valida que los campos longitud máxima de ps9, waitinterval y número de sesión sean numéricos, en caso de que no sean correctas cualquiera de estas premisas se enviara el error correspondiente y cerrada el socket asignado. 2. Una vez validado el Message descriptor, el programa toma la segunda parte correspondiente al Input Header PS9, en esta parte checa los tags del Input Header que se encuentren en la posición correcta y se valida que el campo de longitud total del mensaje PS9 sea numérico. En caso de que no sea satisfactoria la respuesta a estas validaciones se regresara el error correspondiente. 3. Si hasta este momento todo va bien, se hacen las operaciones correspondientes para checar la longitud de la commarea a enviar a la transacción procesadora y se le realiza el START correspondiente, enviando el socket que se tomará para regresar la respuesta y cerrando el socket asignado para recibir la información. 4. Para este esquema existe una variante si el parámetro TIPOUSUARI es USER RACF, TIPOVALIDA es RACF y REQUERIMIENTO del Message Descriptor es LRSS, se tomará el usuario y password que venga en el Message descriptor y se realizará la validación en RACF si es correcto se procederá a realizar el START a la transacción procesadora correspondiente y en caso contrario se regresará el error correspondiente. b) Cuando parámetro de host TIPOREQUER es el valor SESI, nos indicará que el cliente requiere de sesiones de Cics bridge. Bajo un esquema de sesiones primero tiene que firmarse al Cics bridge haciendo el LOGON y una vez “firmado” comenzar a enviar las operaciones correspondientes, una vez terminada su actividad tendrá que dejar la sesión haciendo el correspondiente LOGOFF. 5. Para el requerimiento del MD sea LOGN ó LOGF correspondiente al LOGON y LOGOFF solo es necesario enviar el formato del Message Descriptor, mismo que será validado como el punto 1. En el LOGN se creará una sesión para el usuario enviado en el MD. Para el LOGF será necesario indicar el usuario y número de sesión a la cual se quiere dar de baja. 6.

Cuando se requiera operar alguna transacción se tendrá que enviar una trama de la siguiente forma:

, Pero aquí en el MD se tendrá que indicar el usuario, número de sesión y requerimiento igual a VERY. El programa realizará el punto 1 posteriormente validará que exista la sesión y contenga al usuario indicado, de tal forma que si es correcto realizara el punto 2 y 3, en caso de que no exista la sesión ó que el usuario no corresponda a la sesión se regresará el error correspondiente. 7. Para este esquema también existe una variante si el parámetro TIPOUSUARI es USERRACF , TIPOVALIDA es RACF y REQUERIMIENTO del Message Descriptor es LOGN, se tomará el usuario y password que venga en el Message descriptor y se realizará la validación en RACF si es correcto se procederá a generar la sesión y en caso contrario se regresará el error correspondiente. Esto es solo en el momento del LOGON ya que de esta forma solo hay una validación en RACF y no una por cada petición.

- 20 -

c) Existe también una función cuando parámetro de host TIPOUSUARI es USERRACF , TIPOVALIDA es RACF y REQUERIMIENTO del Message Descriptor es CHPW. Este requerimiento es el cambio de password en el cual solo se envía el formato del Message Descriptor con estos valores además del user-id password y nuevo password encriptados. El Host desencriptará el password y new password tomando la llave de Desencripción correspondiente y tomando el user-id ejecutará el commando CHANGE PASSWORD cambiando el password sea correcto o erróneo regresará el mensaje correspondiente al cliente.

- 21 -

FORMATOS DE SALIDA DE CICS BRIDGE TCP. El formato de salida para cualquiera de las transacciones va ser en el formato PS9 que utilizamos como estándar. Al igual como el formato de entrada, el formato de salida también tiene un Header y su detalle ya sea de error o respuesta aplicativa. De tal modo que cuando una respuesta sea satisfactoria para la arquitectura tendrá el siguiente formato: ...................................... Y cuando exista un error ......................... Los Layouts correspondientes a los formatos de salida son los siguientes: OUTPUT HEADER. Field TTTT PP R

Bytes 4 2 1

Meaning Tag Indicating beginning of output header Protocol Identification Transaction / Service response

P

1

Process Control

- 22 -

Possible Values ‘’ ‘26’ – PS9 (this protocol) ‘1’= OK with COMMIT. It means the Front End should COMMIT the changes (if the COMMIT indicator had the value ‘0’ Altamira architecture is not allowed to do so). ‘2’ = NO OK with COMMIT. It means the Front End should COMMIT the changes even thougth an error has ocurred. ‘3’ = CONFIRMATION REQUESTED with COMMIT (User must confirm an action. Usually associated to a Warning Map and a Next Transaction map to indicate what is the transaction we want to confirm. The changes should be commited). ‘4’= OK with ROLLBACK. It means the Front End should ROLLBACK the changes. ‘5’ = NO OK with ROLLBACK. It means the Front End should ROLLBACK the changes. ‘6’ = CONFIRMATION REQUESTED with ROLLBACK. ’0’ – Not processing errors detected. ‘1’ – Indicates that an architecture error has ocurred. An output format espedified in an map does not exist (Only applicable in traditional Altamira architecture). ‘2’ – Reserved Use. '3' – Indicates that an architecture error has ocurred. The output message has more than 32 Kb. The user should advise CPD check the LOG. '4' – Indicates that an architecture error has ocurred. The Output Copy map or the Preformated Map information has more than 20 Kb. The user should advise CPD to check the LOG. '5' - Indicates that an architecture error has ocurred. The application program informs that the Output Screen is the same that the Input Screen and the Input format does not exist. The user should advise CPD to check the LOG. (Only applicable in

traditional Altamira architecture) '6' - Indicates that an architecture error has ocurred. The application program informs that the Output Screen has been prepared and the Output format does not exist. The user should advise CPD to check the LOG. (Only applicable in traditional Altamira architecture) '7' - Indicates that an architecture error has ocurred. In case of prefortating indicator, the preformat name related to the espedified format is not informed or does not exist. The user should advise CPD to check the LOG. (Only applicable in traditional Altamira architecture) ‘A’ – Indicates that an Abend Error has ocurred. The user should advise CPD to check the LOG. SSSSSSSS

8

Sequence number

NNNNN

5

TTTTT

5

Output message length. Also needed for validation purposes and also to identify the end of the message. (Output Header Length + Output Data Length) Tag Indicating end of output header

Any Alphanumeric set of characters. Front end or middleware will provide this number. Altamira will just give it back. It is used to synchronize back and front end. Any number between 26 and maximum output length.

‘’

Total de longitud: 26 bytes. FORMATOS DE MENSAJES DE SALIDA. .. - Error map. .. - Warning map. .. - Next transaction map. .. - Journal map. .. - Destination map. .. - Output Copy map. .. - Scroll Map. .. - Conversational Authorization map. .. - Unexpected Message map. .. - Preformated Data map. FORMATO DE ERROR. Field TTTT CODERR

Bytes 4 7

Meaning Tag for beginning of error map Error code

NUMVAR

1

Number of variables

ERRVAR1

20

First error variable data

…… ERRVARN

20

Error variable data number N

TTTTT

5

Tag for end of error map

Possible Values ‘’ Any Alphanumeric set of characters following Altamira standard for error names Any value >= 0. When NUMVAR is equal to 0, the Variable fields won´t be sent. Any Alphanumeric set of characters (if NUMVAR > 0) Any Alphanumeric set of characters (if NUMVAR > 1) ‘’

Máxima longitud: ?. Actualmente tenemos un máximo de 2 variables de datos, con 57 bytes.

- 23 -

FORMATO DE OUTPUT COPY. Field TTTT ID IND-PANDOC

Bytes 4 1 1

NUM-DOCUM

1

Meaning Tag for beginning of destination map. ID of the Destination Destination of the format (Screen, Printer, Hard Disk or Jetform Type of document if the output is to document.

PRILIN-DOCUM IMPRESO IDIOMA

2 6 1

Position of the first line to be written in the document. ID of the form to be used Language

TTTTT

5

Tag for end of destination map.

Possible Values ‘’ Any value among 1,..,5 ‘P’ Screen ‘D’ Printer ‘1’ DIN A-4 Normal print. ‘2’ DIN A-4 Compressed print. ‘3’ Sheet ‘5’,’6’,’7’,’8’ Savings books. ‘9’ DIN A-4 in a laser printer ‘C’ Check ‘B’ Band (ribbon) ‘I’ Amount ‘J’ Magnetic Diary ‘R’ Pre-printed document.

ID of the language to be used. ‘’

Maxima longitud: 5 x 21 bytes. Field TTTT T

Bytes 4 1

Meaning Tag for beginning of Output copy map Type of copy

Y

1

Number ID of the DE map which describes the copy destination. 0 means no destination

FFFFFFFF

8

Format name / Output number

?

Data

TTTTT

5

Tag for end of Output Copy Map

Possible Values ‘’ ‘B’ – BMS ‘C’ – COPY ‘0’ ‘1’ ‘2’ ‘3’ ‘4’ ‘5’ Format name that will match with copy name following Altamira Naming Standards, or the output number for the transaction. Copy of the specified type (BMS or standard COPY). ‘’

BMS copy sigue la estructura FILLER [longitud-atributo-campo], con un tamaño máximo de 2000 bytes. En caso de un copy fijo, este consistirá de un número fijo de campos con contenido alfanumérico. Esto permite usar diferentes copias para la misma transacción. El copy usado será definido por el número de salida. Si el destinatario es diferente de 0, debe de existir un mapa destino () que informe el destino para la salida. En el caso de copy fijo el mapa destinatario será siempre 0, como el front-end conocerá el destinatario. Puede haber varios mapas con estructura de copy BMS solo en caso de copy fijo, y ambos tipos son exclusivos (por ejemplo, el mensaje puede contener varios de tipo BMS o uno de tipo copy) Longitud maxima: 20 Kb.

- 24 -

4 Programación concurrente y paralela.

4.1

Introducción.

La programación en paralelo, es una técnica de programación en la que muchas instrucciones se ejecutan simultáneamente o paralelamente. Se basa en el principio de que los problemas grandes se pueden dividir en partes más pequeñas, las cuales se pueden resolverse de forma paralela (no es lo mismo que concurrente). Existen varios tipos de programación en paralelo: paralelismo a nivel de bit, paralelismo a nivel de instrucción, paralelismo a nivel de datos y paralelismo de tareas. Durante muchos años, la programación en paralelo se ha aplicado en la computación de altas prestaciones, pero el interés en ella ha aumentado en los últimos años debido a las restricciones físicas que impiden escalarlo con frecuencia. La computación en paralelo se ha convertido en el paradigma dominante en la arquitectura de computadoras, principalmente en los procesadores mutinúcleo. Sin embargo, recientemente, en los equipos paralelos su consumo de energía se ha convertido en una preocupación. Las computadoras paralelas se pueden clasificar según el nivel de paralelismo que admite su hardware: las computadoras de multinúcleo y multiproceso tienen varios elementos de procesamiento en una sola máquina, mientras que los clusters, los MPP y los grids emplean varias computadoras para trabajar en la misma tarea. Los programas de las computadoras en paralelo, son más difíciles de escribir que los normales secuénciales, porque el paralelismo introduce nuevos tipos de errores de software, siendo las rice condition los más comunes. La comunicación y la sincronización entre las diferentes subtareas son típicamente las grandes barreras para conseguir un buen rendimiento de los programas paralelos. El incremento de velocidad que consigue un programa como resultado del algoritmo paralelizado viene dado por la ley de Amdahl, el cual permite observar si mejora el performance del programa con el paralelismo.

4.2

Programación Multihilo.

En los sistemas operativos un hilo de ejecución, hebra o subproceso es la unidad de procesamiento más pequeña que puede ser planificada por un sistema operativo. La creación de un nuevo hilo es una característica que permite a una aplicación realizar varias tareas a la vez (concurrentemente). Los distintos hilos de ejecución comparten una serie de recursos tales como el espacio de memoria, los archivos abiertos, situación de autenticación, etc. Esta técnica permite simplificar el diseño de una aplicación que debe llevar a cabo distintas funciones simultáneamente. Un hilo es básicamente una tarea que puede ser ejecutada en paralelo o en el mismo intervalo de tiempo con otra tarea. Los hilos de ejecución que comparten los mismos recursos, sumados a estos recursos, son en conjunto conocidos como un proceso. El hecho de que los hilos de ejecución de un mismo proceso compartan los recursos hace que cualquiera de estos hilos pueda modificar éstos. Cuando un hilo modifica un dato en la memoria, los otros hilos acceden a ese dato modificado inmediatamente. Lo que es propio de cada hilo es el contador de programa, la pila de ejecución y el estado del CPU (incluyendo el valor de los registros).

- 25 -

El proceso sigue en ejecución mientras, al menos uno de sus hilos de ejecución siga activo. Cuando el proceso finaliza, todos sus hilos de ejecución también han terminado. Asimismo en el momento en el que todos los hilos de ejecución finalizan, el proceso no existe más y todos sus recursos son liberados. Algunos lenguajes de programación tienen las características de diseño expresamente creadas para permitir a los programadores lidiar con hilos de ejecución (como Java o Delphi, etc). Otros (la mayoría) desconocen la existencia de hilos de ejecución y éstos deben ser creados mediante llamadas de biblioteca especiales que dependen del sistema operativo en el que estos lenguajes están siendo utilizados (como es el caso del C y de C++). Un ejemplo de la utilización de hilos, es tener un hilo atento a la interfaz grafica de usuario (en los iconos, botones, ventanas), mientras otro hilo hace una larga operación internamente. De esta manera el programa responde de manera más ágil a la interacción con el usuario. También pueden ser utilizados por una aplicación servidora para dar servicio a múltiples clientes.

4.3

Modelos y herramientas de programación paralela.

Una computadora en paralelo es un sistema computarizado multi-procesador que soporta programación en paralelo. Se definen dos importantes categorías de computadoras en paralelo, multi-computadoras y centralizados multiprocesadores. Como el nombre lo indica, multi-computadoras es una computadora paralela construida en base de múltiples computadoras y una interconexión de red. El procesador en diferentes computadoras interactúa pasando mensajes a cada una de las otras. En contraste, un centralizado multiprocesador (también llamado simétrico multiprocesador o SMP) es un mas alto sistema integrado en el cual todos los CPU’s comparten acceso a una simple global memoria. Esta memoria compartida soporta comunicación y sincronización de procesos alojados. Paralela programación es la programación en un lenguaje que permite explícitamente indicar como diferentes porciones de la computación pueden ser ejecutados concurrentemente por diferentes procesos OpenMP, es una interfaz de programación de aplicaciones (API) para la programación de multiprocesos y de memoria compartida en múltiples plataformas. Permite añadir concurrencia a los programas escritos en C, C++ y Fortran sobre la base del modelo de ejecución fork-join. Está disponible en muchas arquitecturas, incluidas las plataformas de Unix y de Microsoft Windows. Se compone de un conjunto de directivas del compilador, rutinas de biblioteca, y variables de entorno que influyen el comportamiento en tiempo de ejecución. El OpenMP, es definido en conjunción por un grupo de proveedores de hardware y de software de gran renombre, es un modelo de programación portable y escalable que proporciona a los programadores una interfaz simple y flexible para el desarrollo de aplicaciones paralelas para las plataformas que van desde las computadoras de escritorio hasta las supercomputadoras. Una aplicación construida con un modelo de programación en paralelo híbrido se puede ejecutar en un cluster de computadoras utilizando ambos OpenMP y MPI, o más transparentemente a través de las extensiones de OpenMP para los sistemas de memoria distribuida.

- 26 -

4.4

Modelo y herramientas usados en el proyecto.

El OpenMP C y C++ API’s permite escribir aplicaciones que efectivamente usen múltiples procesadores. Visual C++ soporta la versión OpenMP 2.0 Standard, el cual forma parte de Visual Studio 2008, versión que se genero el código para que la aplicación soporte paralelismo. Directive

Description

atomic

Specifies that a memory location that will be updated atomically.

barrier

Synchronizes all threads in a team; all threads pause at the barrier, until all threads execute the barrier.

critical

Specifies that code is only executed on one thread at a time.

flush (OpenMP)

Specifies that all threads have the same view of memory for all shared objects.

for (OpenMP)

Causes the work done in a for loop inside a parallel region to be divided among threads.

master

Specifies that only the master threadshould execute a section of the program.

ordered (OpenMP Directives)

Specifies that code under a parallelized for loop should be executed like a sequential loop.

parallel

Defines a parallel region, which is code that will be executed by multiple threads in parallel.

sections (OpenMP)

Identifies code sections to be divided among all threads.

single

Lets you specify that a section of code should be executed on a single thread, not necessarily the master thread.

threadprivate

Specifies that a variable is private to a thread.

parallel. Define una región paralela, la cual es el código que será ejecutado por múltiples hilos en

paralelo. #pragma omp parallel [clauses] { block de codigo } Donde, clause (optional) Cero o mas clausulas. En seguida se muestran las cláusulas soportadas por la directiva parallel. •

copyin



default (OpenMP)



firstprivate



if (OpenMP)



num_threads



private (OpenMP)



reduction



shared (OpenMP)

- 27 -

Ejemplo de uso de la directiva parallel: // omp_parallel.cpp // compile with: /openmp #include #include int main() { #pragma omp parallel num_threads(4) { int i = omp_get_thread_num(); printf_s("Hello from thread %d\n", i); } }

- 28 -

5 Criptografía.

5.1

Introducción

Criptología (del griego κρύπτω krypto, «oculto», y γράφως graphos, «escribir», literalmente «escritura oculta») tradicionalmente se ha definido como la parte de la criptología que se ocupa de las técnicas, bien sea aplicadas al arte o la ciencia., que alteran las representaciones lingüísticas de mensajes, mediante técnicas de cifrado y/o codificado, para hacerlos ininteligibles a intrusos (lectores no autorizados) que intercepten esos mensajes. Por tanto el único objetivo de la criptografía era conseguir la confidencialidad de los mensajes. Para ello se diseñaban sistemas de cifrado y códigos. En esos tiempos la única criptografía que había era la llamada criptografía clásica. La aparición de las Tecnologías de la Información y comunicación y el uso masivo de las comunicaciones digitales han producido un número creciente de problemas de seguridad. Las transacciones que se realizan a través de la red pueden ser interceptadas. La seguridad de esta información debe garantizarse. Este desafío ha generalizado los objetivos de la criptografía para ser la parte de la criptografía que se encarga del estudio de los algoritmos, protocolos (se les llama protocolos criptográficos) y sistemas que se utilizan para proteger la información y dotar de seguridad a las comunicaciones y a las entidades que se comunican. Para ello los criptógrafos investigan, desarrollan y aprovechan técnicas matemáticas que les sirven como herramientas para conseguir sus objetivos. Los grandes avances que se han producido en el mundo de la criptografía han sido posibles gracias a los grandes avances que se ha producido en el campo de las matemáticas y las ciencias de la computación. Objetivos de la criptografía .La criptografía actualmente se encarga del estudio de los algoritmos, protocolos y sistemas que se utilizan para dotar de seguridad a las comunicaciones, a la información y a las entidades que se comunican. El objetivo de la criptografía es diseñar, implementar, implantar, y hacer uso de sistemas criptográficos para dotar de alguna forma de seguridad. Por tanto se ocupa de proporcionar: •

Confidencialidad. Es decir garantiza que la información está accesible únicamente a personal autorizado. Para conseguirlo utiliza códigos y técnicas de cifrado.



Integridad. Es decir garantiza la corrección y completitud de la información. Para conseguirlo puede usar por ejemplo: funciones de Hash criptográficas MDC, protocolos de compromiso de bit, o protocolos de notorización electrónica.



No repudio. Es decir proporciona protección frente a que alguna de las entidades implicadas en la comunicación, pueda negar haber participado en toda o parte de la comunicación. Para conseguirlo puede usar por ejemplo firma digital.



Autenticación. Es decir proporciona mecanismos que permiten verificar la identidad del comunicante. Para conseguirlo puede usar por ejemplo: función hash criptográfica MAC o protocolo de conocimiento cero.



Soluciones a problemas de la falta de simultaneidad en la telefirma digital de contratos. Para conseguirlo puede usar por ejemplo: protocolos de transferencia inconsciente.

Un sistema criptográfico es seguro respecto a una tareas si un adversario con capacidades especiales no puede romper esa seguridad, es decir, el atacante no puede realizar esa tarea específica.

- 29 -

La criptografía de Triple DES se llama al algoritmo que hace triple cifrado de tipo DES. También es conocido como TDES o 3DES, fue desarrollado por IBM en 1998. Algoritmo. No llega a ser un cifrado múltiple, porque no son independientes todas las subclases. Este hecho se basa en que DES tiene la característica matemática de no ser un grupo, lo que implica que si se cifra el mismo bloque dos veces con dos claves diferentes se aumenta el tamaño efectivo de la clave. La variante más simple del Triple DES funciona de la siguiente manera:

Donde es el mensaje a cifrar y , y las respectivas claves DES. En la variante 3TDES las tres claves son diferentes; en la variante 2TDES, la primera y tercera clave son iguales. Seguridad. Cuando se descubrió que una clave de 56 bits no era suficiente para evitar un ataque de fuerza bruta, TDES fue elegido como forma de agrandar el largo de la clave sin necesidad de cambiar de algoritmo de cifrado. Este método de cifrado es inmune al ataque por encuentro a medio camino, doblando la longitud efectiva de la clave (112 bits), pero en cambio es preciso triplicar el número de operaciones de cifrado, haciendo este método de cifrado muchísimo más seguro que el DES. Por tanto, la longitud de la clave usada será de 192 bits, aunque como se ha dicho su eficacia solo sea de 112 bits. Usos. El Triple DES está desapareciendo lentamente, siendo reemplazado por el algoritmo AES. Sin embargo, la mayoría de las tarjetas de crédito y otros medios de pago electrónicos tienen como estándar el algoritmo Triple DES (anteriormente usaban el DES). Por su diseño, el DES y por lo tanto el TDES son algoritmos lentos. AES puede llegar a ser hasta 6 veces más rápido y a la fecha no se ha encontrado ninguna vulnerabilidad. Base 64, es un sistema de numeración posiciónala que usa el 64 como base. Es la mayor potencia de dos que puede ser representada usando únicamente los caracteres imprimibles de ASCII. Esto ha propiciado su uso para codificación de correos electrónicos, PGP y otras aplicaciones. Todas las variantes famosas que se conocen con el nombre de Base64 usan el rango de caracteres A-Z, a-z y 0-9 en este orden para los primeros 62 dígitos, pero los símbolos escogidos para los últimos dos dígitos varían considerablemente de unas a otras. Otros métodos de codificación como UUEncode y las últimas versiones de binhex usan un conjunto diferente de 64 caracteres para representar 6 dígitos binarios, pero éstos nunca son llamados Base64.

5.2

TDES y base 64, para el manejado en el proyecto.

Para el proyecto se utilizo el algoritmo TDES con una llave de bits para garantizar la seguridad de la información. También se usa el algoritmo de base 64 para garantizar la conversión de caracteres entres el sistema distribuido y el Host, debido a que uno usa un mapa de caracteres ASCII y el otro EBCDIC, respectivamente.

- 30 -

6 Sistema de comunicación TCP-IP para aplicaciones cliente a Mainframe-Host (SICOTIP). 6.1

Requerimientos.

Antecedentes y situación actual. Las aplicaciones de una institución financiera, en su canal de atención telefónica, el cual esta basada su comunicación con el cliente, en la interacción vía telefónica. Estas aplicaciones distribuidas denominadas GUI’s, IVRs y CTI, las cuales tendrán enlace con el sistema principal MainFrame, donde se centraliza la información de las cuentas de los clientes y toda la información necesaria relacionada con estos. La aplicación GUI de atención telefónica que usaran los asesores, que estarán en los Call Centers (internos o de origen externo, outsoursing), utilizaran las aplicaciones distribuidas para proporcionar los servicios requeridos por los clientes, esto cuando a los asesores les llega la llamada. Los IVRs son los equipos de audio-respuesta, los cuales dan arribo de atención a mas del 80% de las llamadas a nivel nacional de los clientes y no clientes de la empresa Bancaria, los cuales requieren algún servicio a través de las llamadas telefónicas. CTI, es el sistema automático que monitorea y da seguimiento lógico a la llamada durante su recorrido en la red de enlace telefónico (integra la telefonía y call centres). Las aplicaciones GUI en muchas variantes, dependiendo la plataforma de implementación, se comunican al sistema central a través de la red interna de un banco. Todavía ahí empresas que usan un software de emulación de terminales 3270 instalado en las PCS y usando la técnica de “screen scraping” para capturar las pantallas tipo Host (24X80 caracteres) y transformarlas a las ventanas de la IG de los asesores. Este medio de enlace es lento debido a las diferentes transformaciones de información, por lo que el tiempo de la llamada se incrementa siendo superior a 3 minutos en promedio total, y superior a 5 segundos por solicitud al Host. Estos tiempos incrementen el costo de la llamada, reflejándose en un gasto excesivo del mismo. Por lo que la propuesta en este proyecto para algún banco que lo requiera, y que de disminuir los tiempos de la llamada, donde esto implica disminución del gasto de la misma. Para esto se realizo el análisis y planteando la situación actual de alguna empresa bancaria, se propone la solución por medio de comunicación de sockets tipo TCP. En base a esto, se procedió a realizar el análisis del problema, encontrando de el principal problema es el medio de comunicación hacia el Host. Entre las propuestas de solución se encontraron las dos siguientes: MQ Series, software propiedad de IBM el cual proporciona un medio de comunicación asíncrono entre diferentes plataformas. Actualmente ya es una solución estándar en unas empresas. El problema principal es costo de las licencias por equipo, así mismo la incompatibilidad con otras plataformas de software propietario en los IVRs. Otro punto, es el tiempo de comunicación, el cual no disminuye significativamente como para considerarse la solución ideal. Uso de Sockets TCP-IP, siendo el medio mas directo de comunicación entre redes de datos de tipo TCP-IP. En la arquitectura de ASTA sobre Host, recién se tiene la solución de comunicación de Socket denominado CICS Bridge TCP-IP, donde las pruebas iniciales entre equipos distribuidos y el MainFrame tienen tiempos de respuesta de 3 segundos por solicitud. Este mismo esquema en

- 31 -

Host ya cuenta con un servicio de encripción bajo TDES y Base 64, para que garantice un canal mas seguro. Estas dos opciones se presentaron al negocio, indicando que la solución bajo sockets se requiere un desarrollo de un modulo para las IGs, así como la adecuación de las mismas para que puedan comunicarse bajo este protocolo. El área de negocio estuvo de acuerdo con el desarrollo y modificación, procediendo a la creación del requerimiento requisitazo y autorizado, ya con el presupuesto necesario para la solución. Por lo anterior, se determino que la solución más idónea para el problema es implementarla sobre un esquema tipo Sockets TCP-IP en distribuido y CICS Bridge Sockets TCP-IP en Host ASTA. De esto se determina la construcción de un modulo que permita a las aplicaciones distribuidas concertarse por TCP-IP hacia el Host. Por lo que nace la necesidad de crear la aplicación SICOTIP. Presentación General. Se requiere mejorar los tiempos de respuesta de las diferentes aplicaciones distribuidas del canal de Atención Telefónica de una empresa Financiera, para comunicarse al sistema central y disminuir el tiempo total de la llamada de los clientes que accedan a este canal. La solución necesita poder contar de un medio que garantice la integridad y seguridad de la información (canal seguro), así como un medio para minimizar las adaptaciones de comunicación con entidades externas que provean el servicio de atención telefónica (Call Center externos), cuando las necesidades del negocio lo requieran. Cliente. Canal de comunicación de acceso de clientes de un Banco, por vía telefónica. A través de los números locales o del servicio 01800 a nivel nacional. Metas. Mejorar el tiempo de respuesta significativamente al que se cuenta actualmente en el servicio de atención telefónica. Mejorar la satisfacción de atención y servicio de los clientes o no clientes por el Banco a través del medio telefónico. Disminuir el costo de las llamadas, para que en base a esto poder ofrecer más opciones o promociones de productos a través de este canal, que implica mayores ventas. Seguridad de la información de los clientes en el canal de Atención Telefónica. La solución debe soportar la transaccionalidad de llamadas tanto horarios pico y no pico.

Funciones del sistema. El sistema permitirá disminuir el tiempo de respuesta de comunicación hacia el Host, por lo que esto implica disminución de tiempo total de la llamada. El sistema permitirá un canal seguro para la información de los clientes, que viaja por este medio. El sistema contara con un protocolo estándar de comunicación que permita comunicarse adecuadamente con el MainFrame o sistema central.

- 32 -

El sistema aprovechara o explotara en la medida de lo posible la infraestructura para manejo de concurrencia o paralelismo, así como balanceo de cargas. Como beneficio del performance de la aplicación. Facilitar el enlace y reglas de firewall, para nuevas empresas o call centers externos que por necesidad del negocio necesiten conectarse al Host por este medio y aplicaciones.

Atributos del sistema.

Atributo

Detalles

Tiempo de respuesta

Meno al actual. Menor a 5 segundos por transacción.

Uso de los estándares del Banco

Manejo de Sockets TCP-IP, uso de protocolo PS9.

Seguridad

Encripción TDES y Base 64

Tolerancia a fallas

La solución contara con time out’s máximos, en puntos finales de Distribuido y host, para que en base a eso se determine acciones a seguir. En transacciones no criticas, como consultas, se permitirá reenviar 2 o 3 intentos de petición, en caso de no éxito se dará por terminada la solicitud informando del error retornado. En transacciones críticas o contables solo se realizara un intento, en caso de error o no respuesta se informara y se informara al cliente o asesor para que se tome a juicio la acción a seguir.

Plataforma

Windows XP, 7. para el servicio en las PCs clientes Windows Server. Para el servicio Proxy SO-390, ASTA, CICS Bridge TCP-IP. En MainFrame.

Facilidad de enlace a entidades externas

Contara con un modulo de Proxy que permita conectar a cualquier entidad externa comunicarse o adaptarse fácilmente con el Banco.

- 33 -

6.2

Análisis.

Casos de Uso. Diagrama de casos de uso.

Modelo Conceptual inicial.

- 34 -

Casos esenciales de uso. A continuación se indica la clasificación de los casos de uso identificados para el proyecto: Casos primarios de uso. Envió de mensajes Casos secundarios de uso. Servicio Proxy de envió de mensajes. Casos opcionales de uso. Encripción de mensajes.

- 35 -

Caso de uso: Envió de mensajes. Actores: IVR, CTI, Interfaz Grafica de usuario, Call Center Externo. Propósito: recibir mensajes provenientes de alguna de las aplicaciones de Atención Telefónica y enviar este vía sockets al destino Host. Esperar la respuesta del Host y regresarla a la aplicación origen. Descripción: Alguna de las aplicaciones de Atención Telefónica de una empresa Bancaria genera un mensaje de solicitud de información hacia el Host. El mensaje lo recibe el servicio de comunicación tcp-ip, donde el mensaje es validado. Si esta activa la opción de encripción, entonces el mensaje es encriptado con la encripción Tripe Des. El mensaje resultante es pasado a la codificación de base 64. Posteriormente, el mensaje es armado a usar protocolo PS9. El mensaje resultante es enviado por sockets al Host. En su defecto si el solicitante del mensaje es una entidad externa (call center outsourcing) entonces el mensaje es pasado primero a servidor Proxy, el cual tomara el mensaje y lo retransmitirá al Host. El mensaje de respuesta es tratado a la inversa, esto es, se valida el mensaje de salida en PS9. Si esta activo el uso de criptografía, se valida la salida y se quita la codificación base 64, posterior se desencripta usando Tripe DES. El mensaje resultante se retorna a la aplicación solicitante original. Tipo: Primario y esencial. Referencias cruzadas: Funciones: Casos de uso: el caso de uso envió de mensajes, usara el caso de uso encriptar mensaje, en caso necesario. También si el call center es externo, se usara el caso de uso servicio Proxy. Curso normal de los eventos. Acción de los actores

Respuesta del sistema

La aplicación GUI/IVR/CTI envía la cadena de la solicitud al Host al servicio TCP-IP

Recibe el mensaje, realiza validaciones básicas del formato de la cadena. Si esta correcta la cadena, y si esta activo la opción de encripción, entonces envía el mensaje al caso de uso encriptar. Si el mensaje fue encriptado correctamente o si el mensaje no necesito encripción, entonces se formatea el mensaje en protocolo PS9. El mensaje generado se envía al Host a través de sockets TCP o si la aplicación origen es entidad externa, entonces el mensaje es trasmitido también vía sockets a servicio Proxy. El servicio espera la respuesta, si se recibió el mensaje, se valida. En caso de ser correcto, se deformatea quitando PS9. Si el mensaje esta encriptado se envía a caso de uso encripción, del mensaje resultante se regresa a la aplicación origen.

LA aplicación recibe el mensaje de respuesta, donde si la respuesta es correcta se visualiza. En caso de ser un mensaje de error, se muestra una descripción adecuada al asesor o al cliente Este mismo proceso se repite tantas veces como solicitudes realice la aplicación origen.

- 36 -

Caso de uso: Servicio Proxy de envió de mensajes. Actores: Call Center Externo usando la GUI. Propósito: recibir mensajes provenientes de alguna de las aplicaciones de Atención Telefónica y retrasmitir los mensajes al destino Host. Esperar la respuesta del Host y regresarla a la aplicación origen. Descripción: Las aplicaciones GUI que están instaladas en Call Centers Outsoursing envían el mensaje con la solicitud al Host al Servicio TCP-IP, este servicio lo procesa y lo reenvía al servidor Proxy, el cual tomara el mensaje y lo retransmitirá al Host. Se espera respuesta del Host, en caso de haber, se retransmite la trama a la Pc cliente origen. Tipo: Primario y esencial. Referencias cruzadas: Funciones: Casos de uso: el mensaje recibido es originado por el caso de uso envió de mensajes. Curso normal de los eventos. Acción de los actores

Respuesta del sistema

La aplicación GUI envía la cadena de la solicitud al Host al servicio TCP-IP

Recibe el mensaje, procesa el mensaje y el mensaje resultante lo retransmite al servicio Proxy. El servicio Proxy recibe el mensaje del servicio envió de mensajes TCP-IP y lo retransmite al Host. Espera la respuesta del Host, esta respuesta es retornada al servicio envió de mensajes TCPIP original para su validación e interpretación.

LA aplicación recibe el mensaje de respuesta, donde si la respuesta es correcta se visualiza. En caso de ser un mensaje de error, se muestra una descripción adecuada al asesor o al cliente Este mismo proceso se repite tantas veces como solicitudes realice la aplicación origen.

- 37 -

Caso de uso: Encripción de mensajes. Actores: Servicio envió de mensajes TCP-IP. Propósito: recibir mensajes provenientes del servicio envió de mensajes TCP-IP, codificarlos en Tripe DES y al resultado codificarlo a base 64. Descripción: recibir mensajes provenientes del servicio envió de mensajes TCP-IP y realizar la codificación del mensaje usando el cifrado Tripe DES. Si el resultado es correcto, el mensaje obtenido se procesa, convirtiéndolo a base 64. El mensaje resultante es retornado al servicio de envió de mensajes TCP-IP que origino la solicitud Tipo: Primario y esencial. Referencias cruzadas: Funciones: Casos de uso: el mensaje recibido es originado por el caso de uso envió de mensajes. Curso normal de los eventos. Acción de los actores

Respuesta del sistema

La aplicación SDAT VB o Nácar envía la cadena de la solicitud al Host al servicio TCP-IP

Recibe el mensaje, se envía el mensaje a caso de uso encripción de mensajes. El mensaje recibido se encripta usando Tripe Des. El resultado se codifica en base 64. Se retorna el mensaje al servicio envió de mensajes. El servicio de envió de mensaje continua el flujo de trasmisión vía sockets

El mensaje se recibe del Host

Si el mensaje es valido y en formato PS9, se deformatea. Del mensaje resultante, si esta encriptado, se envía a desencriptar. Este mensaje, se quita la codificación Base 64, después se desencripta usando Tripe DES. El mensaje resultante se regresa al servicio de envió de mensajes TCP-IP para que continué el flujo de respuesta.

- 38 -

Diagrama de Actividades.

- 39 -

6.3

Diseño.

Diagrama de secuencia del sistema.

- 40 -

Contratos de operaciones. Sistema SICOTIP envioMensaje(mensajeEntrada, tamañoEntrada, mensajeSalida, tamañoSalida) asignaParametros(IP, Puerto, usoEncripcion) generaSiguienteTrama(mensajeRespuesta)

Nombre: asignacionParamentros( IP:string, Puerto: entero, usoEncripcion: Boolean) Responsabilidades: definir y/o inicializar los valores de los atributos: IP, puerto y usoEncripcion, para su posterior uso. Tipo: Sistema. Salida: Precondiciones: •

Se cuenta con los valores a asignar a los atributos de IP, Puerto y usoEncripcion.

Poscondiciones: •

Se recibirá el valor del atributo IP



Se asignara el valor del atributo Puerto



Se asignara el valor del atributo usoEncripcion.

Nombre: envioMensaje(mensajeEntrada, tamañoEntrada, mensajeSalida, tamañoSalida) Responsabilidad: recibe el mensaje que se requiere enviar al sistema central Host. Si el atributo usoEncripcion tiene valor Trae, entonces se encripta el mensaje. El mensaje encriptado o no se formatea en PS9 y se envía a Host usando sockets. Tipo: Sistema.

Salida: Precondiciones:

- 41 -



Se contara con el mensaje a enviar a Host, el cual también contara con los datos necesarios para la solicitud de la información al área central.

Poscondiciones: •

Se creara la instancia de la clase sevicioTCP-IP.



Se recibirá y validara el mensaje de entrada.



Si el atributo usoEncripcion será con valor de verdad, entonces se creara instancia de la clase Cripto, y se relacionara a la instancia de la clase servicioTCP-IP.



Se enviara el mensaje encriptar(mensaje) a la instancia servicioTCP-IP.



Se creara la instancia de las clases TripeDes y Base64.



Se relacionara las instancias de las clases TripeDes y Base64 a la instancia de la clase Cripto.



Se enviará mensaje generaCripto() a la instancia de la clase TripeDes.



Se enviará mensaje codificar() a la instancia de la clase Base64.



Se creará la instancia de la clase PS9. y se relacionara a la instancia de la clase servicioTCP-IP.



Se enviara mensaje armaEntrada(trama) a la clase PS9.



Se creara instancia de las clases MD, IH y ME. Se vinculara con la instancia de la clase PS9.



Se mandara mensaje genera(trama) a las instancias de las clases MD, IH y ME.



Se creara una instancia de la clase Thread. Para la generación de un hilo de ejecución. Se relacionara a la clase servicioTCP-IP.



La instancia de la clase Thread creara una instancia de la clase Socket, y se vinculara a la primera instancia mencionada.



Se enviara mensaje send(mensaje) a la instancia Socket para enviar la trama por el socket TCP al Host o al servicio Proxy.



Se esperara resultado del Socket por el mensaje recv().



El mensaje de respuesta se deformateara con la instancia de la clase PS9.



Si el mensaje es de topo encriptado. Se desencriptara el mensaje con la instancia de la clase Cripto.



El mensaje resultante se retornara a la instancia de la aplicación origen.

- 42 -

Diagrama de clases.

- 43 -

Diagrama de interacción.

- 44 -

Diagrama de componentes

- 45 -

6.4

Construcción.

Diagrama de Bloque correspondiente a la construcción del los dos módulos del sistema SICOTIP.

Aplicación Conexion:

WinSock

Csockbase

TDESIVR

Ccliente::obj cte

CServidor

CConexHost

CBase64::objB ase64

IConexHost

- 46 -

Aplicación ServerTCP: WinSock

CCmdTarget

CAboutDlg

Csockbase

CDialog

CServerTCPDlgAutoProx y

Ccliente::objcte

CServerTCPDlg CParametros

CCServidor::servidor

CWinApp

CServerTCPApp

Debido a lo extenso de el código fuente del sistema se incluye en el Anexo A.

- 47 -

6.5

Conclusiones y resultados.

Al finalizar la construcción de los dos módulos que componen el proyecto, el modulo cliente y el servidor Proxy-TCP, se procedió a realizar pruebas individuales, después pruebas ínter sistemas. Posteriormente se realizaron pruebas de volumen en un ambiente de desarrollo ya comunicando las aplicaciones distribuidas con el Host, se fueron presentando algunas incidencias pero se fueron resolviendo sin problema. Para realizar la instalación e implementación de las aplicaciones en ambiente de producción, se realizo de manera controlada sin presentar algún problema. Inicialmente se realizo un piloto, integrando sobre este esquema solo una célula, la cual consiste una agrupación de 10 asesores telefónicos, sin presentarse algún problema. Posteriormente de un período de prueba se fueron integrando más células, hasta integrar bajo este esquema dos centros de llamada (call centers) con 300 asesores aproximadamente. Así también, se realizo otro piloto para integrar la aplicación cliente de conexión sockets, para un IVR, y se fueron integrando mas, hasta integrar los 21 IVRs que se tienen en tres sites, donde cada IVR cuenta con 90 puertos. Donde cada puerto es equivalente, a una línea en la cual puede recibir una llamada, por lo tanto, cada IVR puede recibir simultáneamente 90 llamadas al mismo tiempo. Después de un par de meses de uso de la aplicación, en el servidor Proxy, se detecto una incidencia. La cual ocasionaba que se cruzara la información, en la retransmisión de la misma en la respuesta del Host al servidor Proxy y a su vez del servidor a las aplicaciones cliente donde se mandaba la petición original. Después de un análisis y la integración de un log de operaciones de esta aplicación, se detecto el problema y en esta ultima versión del código, ya se cuenta con esta ultima corrección. Donde hasta el momento se sigue trabajando sin problema con las aplicaciones que están bajo este esquema. En la parte del modulo de encripción, solo se usa para las aplicaciones de Interfaz grafica (Call Center) debido a que esta pendiente la integración de este para los IVRs. Para esto, se esta planeando realizar un piloto, con el fin de determinar el performance y poder medir el tiempo de respuesta, y saber que no afecte al tiempo actual de respuesta. En el caso de que se tenga algún problema, o sea, que afecte al performance actual. Entonces, se tendrá que pensar en la alternativa de solución, como puede ser el Cripto AES. Donde la idea, es de poder remplazar al de TDES, que en teoría es mucho más rapido y seguro. Se tendría contemplado desarrollar este modulo, en una siguiente etapa, como un proyecto adoptativo evolutivo, o sea integrando nueva funcionalidad al sistema actual.

- 48 -

7 Referencias.

• • • • • •

Titulo: Introduction to the New Mainframe: z/OS Basics Autores: Mike Ebbers, Wayne O’Brien, Bill Ogden. Editorial: International Business Machines Corporation 2005, 2006. Titulo: ASTA. Manual de Usuario, Arquitectura Clásica. Editorial: Alnova Titulo: Curso de Formación de Arquitectura Altamira para desarrolladores Editorial: Andersen Consulting. Titulo: MSDN, Visual Studio 2008. Editorial: Microsoft Titulo: UML y Patrones. Introducción al análisis y diseño orientado a objetos. Autor: Craig Larman Editorial: Pearson, Prentice may. Titulo: Parallel programming in c with MPI and OPENMP Autor: Michael J. Quinn Editorial: McGraw Hill, Higher Education.

- 49 -

Anexo A. Código fuente. Aplicación Conexion: // ConexHost.h : Declaration of the CConexHost #ifndef __CONEXHOST_H_ #define __CONEXHOST_H_ #include "resource.h"

// main symbols

///////////////////////////////////////////////////////////////////////// //// // CConexHost class ATL_NO_VTABLE CConexHost : public CComObjectRootEx, public CComCoClass, public IConexHost { public: CConexHost() { } DECLARE_REGISTRY_RESOURCEID(IDR_CONEXHOST) DECLARE_PROTECT_FINAL_CONSTRUCT() BEGIN_COM_MAP(CConexHost) COM_INTERFACE_ENTRY(IConexHost) END_COM_MAP() // IConexHost public: BOOL InsertSubCadCadena(char *subcad, char *cadena, int posini, int numcaract); BOOL ObtenSubCadena(char *cadfuente, char *subcaddestino, int posini, int numcarateres); int ProcesaEncripcion(char * msgEntrada, char *MsgSalida, int TipoSolicitud, int *TamSalida); BOOL GeneraConsecutivoStr4(char *pcadCosecutivo, int pValorActual); BOOL CountCadena1(char* cadfuente, int * numcarateres); //STDMETHOD(EnviaMensajeHost)(/*[out,retval]*/ unsigned char* nDato, unsigned char* ndirIP, int * nPuerto, int * lpnResultado); STDMETHOD(EnviaMensajeHost)(/*[out,retval]*/ unsigned char* nDato, unsigned char* nSalida, int * nLonSal, unsigned char* ndirIP, int * nPuerto, int nTipo, int * lpnResultado); STDMETHOD(EnviaMsjHostEncripto)(/*[out,retval]*/ unsigned char* nDato, unsigned char* nSalida, int * nLonSal, unsigned char* ndirIP, int * nPuerto, int nTipo, int * lpnResultado); STDMETHOD(ArmaEnvioMEPseudoConversSG_SC)(/*[out,retval]*/ unsigned char* nStrEntrada, unsigned char* nStrSalidaME, int * nLongTrama, int * lpnResultado); STDMETHOD(CountCadena)(/*[out,retval]*/ unsigned char* cadfuente, int * numcarateres, int * lpnResultado);

- 50 -

STDMETHOD(Cripto)(/*[out,retval]*/ unsigned char* nDato, unsigned char* nSalida, int * TipoSolicitud, int *TamSalida, int * lpnResultado); char mMensaje[32000]; }; #endif //__CONEXHOST_H_

// ConexHost.cpp : Implementation of CConexHost #include "stdafx.h" //#include #include "socstr.h" #include "Conexion.h" #include "ConexHost.h" #include "TDESIVR.h" #include "Base64.h" ///////////////////////////////////////////////////////////////////////// //// // CConexHost

//typedef ULONG (CALLBACK* LPFNDLLFUNC1)(char*, char*, int*, char*); //typedef ULONG (CALLBACK* LPFNDLLFUNC1)(char*, char*, int*, char*);

STDMETHODIMP CConexHost::EnviaMensajeHost(unsigned char* nDato, unsigned char* nSalida, int * nLonSal, unsigned char* ndirIP, int * nPuerto, int nTipo, int *lpnResultado ) { // Para Llamar la Dll //HINSTANCE hDLL; // Handle to DLL //LPFNDLLFUNC1 lpfnDllFunc1; // Function pointer //DWORD dwParam1; //UINT uParam2, uReturnVal; //char MsgEnt[161], MsgSal[161];

//Implementacion de la conenexion a Host int Error=0; int Enviados=0; int Recibidos=0; int Longitud=0; int indice =0; //int nSocketType = SOCK_STREAM,lintBub;

//DEFINICION DE IP Y PUERTO LPCTSTR lpszSocketAddress = //LPCTSTR lpszSocketAddress //LPCTSTR lpszSocketAddress //LPCTSTR lpszSocketAddress

(char *)ndirIP; //DESARROLLO Y TEST = "150.50.102.15"; //DESARROLLO Y TEST = "150.100.246.44"; //PRODUCCION = "150.50.102.15"; //Desarrollo

UINT nSocketPort=*nPuerto; //UINT nSocketPort=3550; //Produccion

- 51 -

//UINT nSocketPort=3555;

//Produccion

//UINT nSocketPort=3224;

//Test

//UINT nSocketPort=3216; //puerto Desarrollo

//char Mensaje[50000]=""; char MensajeRecib[32000]=""; char *pmensaje, *ptrRespuesta=MensajeRecib; char NumSesion[9]=""; char *lMensajeEntrada=(char *)nDato; char *lMensajeSalida=(char *)nSalida; char MensajeError[100]="",lNumError[20]=""; pmensaje=lMensajeEntrada;

//AfxMessageBox(lMensajeEntrada,MB_YESNO); strcpy((char *)nSalida,""); WORD wVersionRequested; WSADATA wsaData; int err; BOOL respuesta=false; wVersionRequested = MAKEWORD( 2, 2 ); //BOOL AfxSocketInit( WSADATA* lpwsaData = NULL ); //respuesta= AfxSocketInit( &wsaData);

err = WSAStartup( wVersionRequested, &wsaData ); if ( err != 0 ) { return S_OK; }

/* /* /* /* /*

Confirm that the WinSock DLL supports 2.2.*/ Note that if the DLL supports versions greater than 2.2 in addition to 2.2, it will still return 2.2 in wVersion since that is the version we requested.

*/ */ */ */

if ( LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 2 ) { /* Tell the user that we could not find a usable */ /* WinSock DLL. */ WSACleanup( ); return S_OK; }

//************************************ /* The WinSock DLL is acceptable. Proceed. */

- 52 -

//************************************ CCliente objcte(lpszSocketAddress,nSocketPort); //************Validacion si uso de Encripcion****** char MsgSalCripto[32000]="", MsgSub1[32000]="", MsgSub2[32000]="",strLongitud[10]=""; int ResultCripto=0, tamCripto=0,i=0, *ptrTamCripto=&tamCripto; char *ptrSub2=MsgSub2; char tmpcadena[10]=""; for( i=0; im_pAutoProxy = NULL; AfxOleUnlockApp(); } void CServerTCPDlgAutoProxy::OnFinalRelease() { // When the last reference for an automation object is released // OnFinalRelease is called. The base class will automatically // deletes the object. Add additional cleanup required for your // object before calling the base class. CCmdTarget::OnFinalRelease(); } BEGIN_MESSAGE_MAP(CServerTCPDlgAutoProxy, CCmdTarget) //{{AFX_MSG_MAP(CServerTCPDlgAutoProxy) // NOTE - the ClassWizard will add and remove mapping macros here. //}}AFX_MSG_MAP END_MESSAGE_MAP() BEGIN_DISPATCH_MAP(CServerTCPDlgAutoProxy, CCmdTarget) //{{AFX_DISPATCH_MAP(CServerTCPDlgAutoProxy) // NOTE - the ClassWizard will add and remove mapping macros here. //}}AFX_DISPATCH_MAP END_DISPATCH_MAP() // Note: we add support for IID_IServerTCP to support typesafe binding // from VBA. This IID must match the GUID that is attached to the // dispinterface in the .ODL file. // {4F07CD07-8179-4624-8EA6-080D1563F8EE} static const IID IID_IServerTCP = { 0x4f07cd07, 0x8179, 0x4624, { 0x8e, 0xa6, 0x8, 0xd, 0x15, 0x63, 0xf8, 0xee } }; BEGIN_INTERFACE_MAP(CServerTCPDlgAutoProxy, CCmdTarget) INTERFACE_PART(CServerTCPDlgAutoProxy, IID_IServerTCP, Dispatch) END_INTERFACE_MAP() // The IMPLEMENT_OLECREATE2 macro is defined in StdAfx.h of this project // {DA04FF49-EB17-4D98-9CBB-7889A7291471} IMPLEMENT_OLECREATE2(CServerTCPDlgAutoProxy, "ServerTCP.Application", 0xda04ff49, 0xeb17, 0x4d98, 0x9c, 0xbb, 0x78, 0x89, 0xa7, 0x29, 0x14, 0x71) ///////////////////////////////////////////////////////////////////////// //// // CServerTCPDlgAutoProxy message handlers // Parametros.h: interface for the CParametros class. // //////////////////////////////////////////////////////////////////////

- 89 -

#if !defined(AFX_PARAMETROS_H__1B530A4A_C351_47B9_B47D_63ACF2601F44__INCLUDED _) #define AFX_PARAMETROS_H__1B530A4A_C351_47B9_B47D_63ACF2601F44__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 class CParametros { public: int m_puertoHost; CString m_ipHost; long maxDatosEntSal; long tamSalida; long tamEntrada; char * pstrDatosSalida; char * pstrDatosEntrada; int SockProc; CParametros(); virtual ~CParametros(); }; #endif // !defined(AFX_PARAMETROS_H__1B530A4A_C351_47B9_B47D_63ACF2601F44__INCLUDED _)

// Parametros.cpp: implementation of the CParametros class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "ServerTCP.h" #include "Parametros.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CParametros::CParametros() { } CParametros::~CParametros() {

- 90 -

}

// ServerTCP.h : main header file for the SERVERTCP application // #if !defined(AFX_SERVERTCP_H__1A43E420_B41F_4C7D_BDD4_8A2EC9E53734__INCLUDED_ ) #define AFX_SERVERTCP_H__1A43E420_B41F_4C7D_BDD4_8A2EC9E53734__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #ifndef __AFXWIN_H__ #error include 'stdafx.h' before including this file for PCH #endif #include "resource.h"

// main symbols

///////////////////////////////////////////////////////////////////////// //// // CServerTCPApp: // See ServerTCP.cpp for the implementation of this class // class CServerTCPApp : public CWinApp { public: CServerTCPApp(); // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CServerTCPApp) public: virtual BOOL InitInstance(); //}}AFX_VIRTUAL // Implementation //{{AFX_MSG(CServerTCPApp) // NOTE - the ClassWizard will add and remove member functions here. // DO NOT EDIT what you see in these blocks of generated code ! //}}AFX_MSG DECLARE_MESSAGE_MAP() };

///////////////////////////////////////////////////////////////////////// //// //{{AFX_INSERT_LOCATION}} // Microsoft Visual C++ will insert additional declarations immediately before the previous line.

- 91 -

#endif // !defined(AFX_SERVERTCP_H__1A43E420_B41F_4C7D_BDD4_8A2EC9E53734__INCLUDED_ )

// ServerTCP.cpp : Defines the class behaviors for the application. // #include "stdafx.h" #include "ServerTCP.h" #include "ServerTCPDlg.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////// //// // CServerTCPApp BEGIN_MESSAGE_MAP(CServerTCPApp, CWinApp) //{{AFX_MSG_MAP(CServerTCPApp) // NOTE - the ClassWizard will add and remove mapping macros here. // DO NOT EDIT what you see in these blocks of generated code! //}}AFX_MSG ON_COMMAND(ID_HELP, CWinApp::OnHelp) END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////// //// // CServerTCPApp construction CServerTCPApp::CServerTCPApp() { // TODO: add construction code here, // Place all significant initialization in InitInstance } ///////////////////////////////////////////////////////////////////////// //// // The one and only CServerTCPApp object CServerTCPApp theApp; ///////////////////////////////////////////////////////////////////////// //// // CServerTCPApp initialization BOOL CServerTCPApp::InitInstance() { if (!AfxSocketInit()) {

- 92 -

AfxMessageBox(IDP_SOCKETS_INIT_FAILED); return FALSE; } // Initialize OLE libraries if (!AfxOleInit()) { AfxMessageBox(IDP_OLE_INIT_FAILED); return FALSE; } AfxEnableControlContainer(); // Standard initialization // If you are not using these features and wish to reduce the size // of your final executable, you should remove from the following // the specific initialization routines you do not need. #ifdef _AFXDLL Enable3dControls(); shared DLL #else Enable3dControlsStatic(); statically #endif

// Call this when using MFC in a

// Call this when linking to MFC

// Parse the command line to see if launched as OLE server if (RunEmbedded() || RunAutomated()) { // Register all OLE server (factories) as running. This enables the // OLE libraries to create objects from other applications. COleTemplateServer::RegisterAll(); } else { // When a server application is launched stand-alone, it is a good idea // to update the system registry in case it has been damaged. COleObjectFactory::UpdateRegistryAll(); } CServerTCPDlg dlg; m_pMainWnd = &dlg; int nResponse = dlg.DoModal(); if (nResponse == IDOK) { // TODO: Place code here to handle when the dialog is // dismissed with OK } else if (nResponse == IDCANCEL) { // TODO: Place code here to handle when the dialog is // dismissed with Cancel }

- 93 -

// Since the dialog has been closed, return FALSE so that we exit the // application, rather than start the application's message pump. return FALSE; }

// ServerTCPDlg.h : header file // #if !defined(AFX_SERVERTCPDLG_H__5D44512B_F398_4187_9C0B_E2592151AC9C__INCLUD ED_) #define AFX_SERVERTCPDLG_H__5D44512B_F398_4187_9C0B_E2592151AC9C__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 class CServerTCPDlgAutoProxy; ///////////////////////////////////////////////////////////////////////// //// // CServerTCPDlg dialog class CServerTCPDlg : public CDialog { DECLARE_DYNAMIC(CServerTCPDlg); friend class CServerTCPDlgAutoProxy; // Construction public: CServerTCPDlg(CWnd* pParent = NULL); virtual ~CServerTCPDlg();

// standard constructor

// Dialog Data //{{AFX_DATA(CServerTCPDlg) enum { IDD = IDD_SERVERTCP_DIALOG }; CString m_ipServer; CString m_ipHost; int m_puertoHost; int m_PuertoServer; //}}AFX_DATA // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CServerTCPDlg) protected: virtual void DoDataExchange(CDataExchange* pDX); support //}}AFX_VIRTUAL // Implementation protected: CServerTCPDlgAutoProxy* m_pAutoProxy; HICON m_hIcon;

- 94 -

// DDX/DDV

BOOL CanExit(); // Generated message map functions //{{AFX_MSG(CServerTCPDlg) virtual BOOL OnInitDialog(); afx_msg void OnSysCommand(UINT nID, LPARAM lParam); afx_msg void OnPaint(); afx_msg HCURSOR OnQueryDragIcon(); afx_msg void OnClose(); virtual void OnOK(); virtual void OnCancel(); afx_msg void OnEjecuta(); afx_msg void OnFin(); afx_msg void OnSetfocusIpServer(); afx_msg void OnModifconfig(); afx_msg void OnCheckConfig(); //}}AFX_MSG DECLARE_MESSAGE_MAP() }; //{{AFX_INSERT_LOCATION}} // Microsoft Visual C++ will insert additional declarations immediately before the previous line. #endif // !defined(AFX_SERVERTCPDLG_H__5D44512B_F398_4187_9C0B_E2592151AC9C__INCLUD ED_)

// ServerTCPDlg.cpp : implementation file // #include #include #include #include

"stdafx.h" "ServerTCP.h" "ServerTCPDlg.h" "DlgProxy.h"

#include #include "servidor.h" #include "Parametros.h" #include

#ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////// //// // CAboutDlg dialog used for App About class CAboutDlg : public CDialog { public:

- 95 -

CAboutDlg(); // Dialog Data //{{AFX_DATA(CAboutDlg) enum { IDD = IDD_ABOUTBOX }; //}}AFX_DATA // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CAboutDlg) protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL // Implementation protected: //{{AFX_MSG(CAboutDlg) //}}AFX_MSG DECLARE_MESSAGE_MAP() }; CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) { //{{AFX_DATA_INIT(CAboutDlg) //}}AFX_DATA_INIT } void CAboutDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CAboutDlg) //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) //{{AFX_MSG_MAP(CAboutDlg) // No message handlers //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////// //// // CServerTCPDlg dialog IMPLEMENT_DYNAMIC(CServerTCPDlg, CDialog); CServerTCPDlg::CServerTCPDlg(CWnd* pParent /*=NULL*/) : CDialog(CServerTCPDlg::IDD, pParent) { //{{AFX_DATA_INIT(CServerTCPDlg) m_ipServer = _T(""); m_ipHost = _T(""); m_puertoHost = 0; m_PuertoServer = 0; //}}AFX_DATA_INIT // Note that LoadIcon does not require a subsequent DestroyIcon in Win32

- 96 -

} CServerTCPDlg::~CServerTCPDlg() { // If there is an automation proxy for this dialog, set // its back pointer to this dialog to NULL, so it knows // the dialog has been deleted. if (m_pAutoProxy != NULL) m_pAutoProxy->m_pDialog = NULL; } void CServerTCPDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CServerTCPDlg) DDX_Text(pDX, IDC_IP_SERVER, m_ipServer); DDV_MaxChars(pDX, m_ipServer, 15); DDX_Text(pDX, IDC_IP_HOST, m_ipHost); DDV_MaxChars(pDX, m_ipHost, 15); DDX_Text(pDX, IDC_PUERTO_HOST, m_puertoHost); DDV_MinMaxInt(pDX, m_puertoHost, 0, 999999); DDX_Text(pDX, IDC_PUERTO_SERVER, m_PuertoServer); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CServerTCPDlg, CDialog) //{{AFX_MSG_MAP(CServerTCPDlg) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_WM_CLOSE() ON_BN_CLICKED(IDEJECUTA, OnEjecuta) ON_BN_CLICKED(IDC_FIN, OnFin) ON_EN_SETFOCUS(IDC_IP_SERVER, OnSetfocusIpServer) ON_BN_CLICKED(IDC_MODIFCONFIG, OnModifconfig) ON_BN_CLICKED(IDC_CHECK1, OnCheckConfig) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////// //// // CServerTCPDlg message handlers const int MaxLineas=100; CEvent EvTerminar(FALSE, TRUE); BOOL banderaProceso = TRUE; UINT ThreadProc( LPVOID pdialog) { EvTerminar.ResetEvent(); CSingleLock slTerminar(&EvTerminar); CServerTCPDlg *pSDlg=(CServerTCPDlg *)pdialog; //CParametros *pParam=(CParametros *)pSDlg->GetDlgItem(IDC_EDIT1); CString ip_server=pSDlg->m_ipServer; CString ip_host=pSDlg->m_ipHost; int puerto_server=pSDlg->m_PuertoServer ;

- 97 -

int puerto_host=pSDlg->m_puertoHost; char DatosEntrada[32000]=""; char DatosSalida[32000]=""; long cuantosLeidos=0; long datosenviados=0; CParametros param; param.m_ipHost =ip_host; param.m_puertoHost =puerto_host;

banderaProceso=TRUE; /* for(int i=0; im_IPDir,pSDlg->m_IPPuerto); //CServidor servidor("150.100.102.142",3220); CServidor servidor(ip_server,puerto_server); while(1) { for(int i=0; iAppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); } } // Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon // TODO: Add extra initialization here m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); m_pAutoProxy = NULL; CEdit *p_EditIpServer = (CEdit *)GetDlgItem(IDC_IP_SERVER); p_EditIpServer->EnableWindow(FALSE); CEdit *p_EditPuertoServer = (CEdit *)GetDlgItem(IDC_PUERTO_SERVER); p_EditPuertoServer->EnableWindow(FALSE); CEdit *p_EditIpHost = (CEdit *)GetDlgItem(IDC_IP_HOST); p_EditIpHost->EnableWindow(FALSE); CEdit *p_EditPuertoHost = (CEdit *)GetDlgItem(IDC_PUERTO_HOST); p_EditPuertoHost->EnableWindow(FALSE); CButton *p_BotonModifica=(CButton *)GetDlgItem(IDC_MODIFCONFIG); p_BotonModifica->EnableWindow(FALSE); //Anexar datos de Archivo //Abre el archivo en la ruta actual del ejecutable, en este caso del proyecto. if( (stream = fopen( "ippuerto.txt", "r+" )) == NULL ) return TRUE; fscanf(stream,"%s",ip); fscanf(stream,"%s",puerto); fscanf(stream,"%s",ip_Host); fscanf(stream,"%s",puerto_Host); fclose(stream); //AfxMessageBox(_T(ip) ,MB_OK); //AfxMessageBox(_T(puerto) ,MB_OK); //AfxMessageBox(_T(ip_Host) ,MB_OK);

- 99 -

//AfxMessageBox(_T(puerto_Host) ,MB_OK); m_ipServer = _T(ip); m_PuertoServer = atoi( puerto ); m_ipHost = _T(ip_Host); m_puertoHost = atoi(puerto_Host); UpdateData(FALSE); return TRUE; // return TRUE

unless you set the focus to a control

} void CServerTCPDlg::OnSysCommand(UINT nID, LPARAM lParam) { if ((nID & 0xFFF0) == IDM_ABOUTBOX) { CAboutDlg dlgAbout; dlgAbout.DoModal(); } else { CDialog::OnSysCommand(nID, lParam); } } // If you add a minimize button to your dialog, you will need the code below // to draw the icon. For MFC applications using the document/view model, // this is automatically done for you by the framework. void CServerTCPDlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // device context for painting SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0); // Center icon in client rectangle int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; // Draw the icon dc.DrawIcon(x, y, m_hIcon); } else { CDialog::OnPaint(); } } // The system calls this to obtain the cursor to display while the user drags // the minimized window.

- 100 -

HCURSOR CServerTCPDlg::OnQueryDragIcon() { return (HCURSOR) m_hIcon; } // Automation servers should not exit when a user closes the UI // if a controller still holds on to one of its objects. These // message handlers make sure that if the proxy is still in use, // then the UI is hidden but the dialog remains around if it // is dismissed. void CServerTCPDlg::OnClose() { if (CanExit()) CDialog::OnClose(); } void CServerTCPDlg::OnOK() { if (CanExit()) CDialog::OnOK(); } void CServerTCPDlg::OnCancel() { if (CanExit()) CDialog::OnCancel(); } BOOL CServerTCPDlg::CanExit() { // If the proxy object is still around, then the automation // controller is still holding on to this application. Leave // the dialog around, but hide its UI. if (m_pAutoProxy != NULL) { ShowWindow(SW_HIDE); return FALSE; } return TRUE; } void CServerTCPDlg::OnEjecuta() { // TODO: Add your control notification handler code here EvTerminar.SetEvent(); AfxBeginThread(ThreadProc,this); /* char DatosEntrada[32000]; char DatosSalida[32000]; long cuantosLeidos; long datosenviados;

banderaProceso=TRUE; //CServidor servidor((LPCSTR)pSDlg->m_IPDir,pSDlg->m_IPPuerto);

- 101 -

CServidor servidor("150.100.102.142",3220); while(1) { if(servidor.servicio(DatosEntrada,DatosSalida,32000,cuantosLeidos,datosen viados,100)==OK) { } else if(banderaProceso==FALSE) break; }//fin while */

//Desabilitar control y activar bandera para que posteriormente el usuario pueda cancerlar el //Server atravez de otro pushbutton CButton *p_Boton=(CButton *)GetDlgItem(IDEJECUTA); p_Boton->EnableWindow(FALSE); } void CServerTCPDlg::OnFin() { // TODO: Add your control notification handler code here banderaProceso=FALSE; CButton *p_Boton=(CButton *)GetDlgItem(IDEJECUTA); p_Boton->EnableWindow(TRUE); } void CServerTCPDlg::OnSetfocusIpServer() { // TODO: Add your control notification handler code here } void CServerTCPDlg::OnModifconfig() { // TODO: Add your control notification handler code here UpdateData(TRUE); /*m_ipServer = _T(ip); m_PuertoServer = _T(puerto); m_ipHost = _T(ip_Host); m_puertoHost = _T(puerto_Host); */ } void CServerTCPDlg::OnCheckConfig() { // TODO: Add your control notification handler code here CButton *p_Boton=(CButton *)GetDlgItem(IDC_CHECK1); if (p_Boton->GetCheck()==1)

- 102 -

{ CEdit *p_EditIpServer = (CEdit *)GetDlgItem(IDC_IP_SERVER); p_EditIpServer->EnableWindow(TRUE); CEdit *p_EditPuertoServer = (CEdit *)GetDlgItem(IDC_PUERTO_SERVER); p_EditPuertoServer->EnableWindow(TRUE); CEdit *p_EditIpHost = (CEdit *)GetDlgItem(IDC_IP_HOST); p_EditIpHost->EnableWindow(TRUE); CEdit *p_EditPuertoHost = (CEdit *)GetDlgItem(IDC_PUERTO_HOST); p_EditPuertoHost->EnableWindow(TRUE); CButton *p_BotonModifica=(CButton *)GetDlgItem(IDC_MODIFCONFIG); p_BotonModifica->EnableWindow(TRUE); } else { CEdit *p_EditIpServer = (CEdit *)GetDlgItem(IDC_IP_SERVER); p_EditIpServer->EnableWindow(FALSE); CEdit *p_EditPuertoServer = (CEdit *)GetDlgItem(IDC_PUERTO_SERVER); p_EditPuertoServer->EnableWindow(FALSE); CEdit *p_EditIpHost = (CEdit *)GetDlgItem(IDC_IP_HOST); p_EditIpHost->EnableWindow(FALSE); CEdit *p_EditPuertoHost = (CEdit *)GetDlgItem(IDC_PUERTO_HOST); p_EditPuertoHost->EnableWindow(FALSE); CButton *p_BotonModifica=(CButton *)GetDlgItem(IDC_MODIFCONFIG); p_BotonModifica->EnableWindow(FALSE); } }

// Servidor.h: interface for the CServidor class. // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_SERVIDOR_H__5B8F2810_EE0F_43E0_B391_8ACCCA49E3E5__INCLUDED_) #define AFX_SERVIDOR_H__5B8F2810_EE0F_43E0_B391_8ACCCA49E3E5__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #include "sockbase.h" #include "Parametros.h" class CServidor : public Csockbase { long bytes_recibidos; struct sockaddr_in addrservicio,addrcliente; public: CServidor(const char *SrcIPAddr=0,int IPPort=0); virtual ~CServidor(); int servicio(char *bufdatosIn, char *bufdatosOut,long maxdatos, long &datosleidos, long &datosenviados,int timeout, CParametros parametros);

- 103 -

int GetPort(); char *GetAddr(); int GetPortUltimoServicio(); char *GetAddrUltimoServicio(); int GetPortUltimoCliente(); char *GetAddrUltimoCliente(); }; #endif // !defined(AFX_SERVIDOR_H__5B8F2810_EE0F_43E0_B391_8ACCCA49E3E5__INCLUDED_)

// Servidor.cpp: implementation of the CServidor class. // ////////////////////////////////////////////////////////////////////// #include #include #include #include #include #include

"stdafx.h" "ServerTCP.h" "Servidor.h" "Cliente.h" "Parametros.h"

#ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CServidor::CServidor(const char *SrcIPAddr,int IPPort) { if (( sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) AfxMessageBox(_T("Error de socket...") ,MB_OK); //throw("Error creando socket SOCK_STREAM"); memset(&addr, 0, sizeof (addr)); addr.sin_family = AF_INET; if(!SrcIPAddr) addr.sin_addr.s_addr = INADDR_ANY; else addr.sin_addr.s_addr= inet_addr(SrcIPAddr); addr.sin_port = htons(IPPort); lenaddr=sizeof(addr); //Se asocia el socket TCP a la direccion de recepcion, //Es la direccion de escucha del Servidor if (bind (sock, (struct sockaddr *) &addr, lenaddr) == -1 ) AfxMessageBox(_T("Error de bind...") ,MB_OK); //throw ("Error en bind"); if(getsockname(sock,(struct sockaddr *)&addr,&lenaddr)==-1) AfxMessageBox(_T("Error de getsockname...") ,MB_OK); //throw ("error en getsockname"); listen(sock,5); }

- 104 -

UINT ThreadSockProc( LPVOID pdialog) { int iErrorLong=0; //Manejo de archivo para grabar log de depuracion en produccion. char strMensajeEnt[32000]=""; char strTmp[10]=""; char strMensaje[50]=""; //AfxMessageBox(_T(strMensaje) ,MB_OK); time_t ltime; time( <ime ); char *strtime=ctime(<ime ); //AfxMessageBox(_T(strtime) ,MB_OK); strcpy(strTmp,""); FILE *stream; char strNameFile[50]="log"; strncpy(strTmp, strtime,3); strcat(strNameFile, strTmp); strncpy(strTmp, strtime+4,3); strcat(strNameFile, strTmp); strncpy(strTmp, strtime+8,2); strcat(strNameFile, strTmp); strcat(strNameFile, ".txt"); if( (stream = fopen(strNameFile , "a+" )) == NULL ) AfxMessageBox(_T("Error al abrir archivo log*.txt...") ,MB_OK);

CParametros *ptrobjParametros = (CParametros *)pdialog; //Recibe los datos de entrada del Socket aceptado, en base a los parametros pasados. //Se comenta y se modifica para pruebas, y eleminacion de problemas. //iErrorLong =recv(ptrobjParametros->SockProc ,ptrobjParametros>pstrDatosEntrada,ptrobjParametros->maxDatosEntSal ,0); iErrorLong =recv(ptrobjParametros->SockProc ,strMensajeEnt,32000 ,0); if (iErrorLong < 0) { fprintf(stream,"Tam Ent: %i\n",iErrorLong); //AfxMessageBox(_T("Error de recv de Cte...") ,MB_OK); fclose(stream); return -1; } //Se comenta para correccion //ptrobjParametros->tamEntrada=iErrorLong; //int tamEnt=ptrobjParametros->tamEntrada; //char *ptrMsg1=ptrobjParametros->pstrDatosEntrada; char *ptrMsg1=strMensajeEnt; //fprintf(stream,"Como es recibida: %s\n",ptrMsg1); //Meter modificacion para que la trama de entrada se recupere la longitud de la cadena y atraves de //esta corta la longitud que debe de ser char cadTamTrama[6]="";

- 105 -

int j=0; for( j=0; j < 5;j++) *(cadTamTrama+j)=*(ptrMsg1+9+j); *(cadTamTrama+j)='\0'; j=0; j = atoi(cadTamTrama); //Modificacion y se comenta para usar la long que viene en el MD *(ptrMsg1+j)='\0'; //*(ptrMsg1+iErrorLong)='\0';

//Graba cadena acotada por longitud, descomentar para validar problemas //fprintf(stream,"Trama a enviar y acotada: %s\n",ptrMsg1); //fprintf(stream,"Tam Ent: %i\n",j); fclose(stream); //fprintf(stream,"Trama a enviar y acotada: %s\n",ptrobjParametros>pstrDatosEntrada); //fprintf(stream,"Tam Ent: %i\n",iErrorLong);

//fclose(stream); //Fin manejo de archivo log // throw("Error en recv"); //*************************** //Retrasmite la informacion a la IP de Host CCliente objCte(ptrobjParametros->m_ipHost,ptrobjParametros>m_puertoHost); //CCliente objCte("150.50.102.15",3224); //comentado para pruebas //objCte.PedirServicio(ptrobjParametros>pstrDatosEntrada,ptrobjParametros->tamEntrada,ptrobjParametros>pstrDatosSalida,(long *)&ptrobjParametros->tamSalida ); if( (stream = fopen(strNameFile , "a+" )) == NULL ) AfxMessageBox(_T("Error al abrir archivo log*.txt...") ,MB_OK); if(*ptrMsg1==' ' || *ptrMsg1=='\0') { //AfxMessageBox(_T("Error al recibir trama entrada en servidor") ,MB_OK); fprintf(stream,"Trama erronea: %s\n",ptrobjParametros>pstrDatosEntrada); fclose(stream); return -1; } fclose(stream); //Se comenta oara correccion de problema //objCte.PedirServicio(ptrMsg1,ptrobjParametros>tamEntrada,ptrobjParametros->pstrDatosSalida,(long *)&ptrobjParametros>tamSalida ); objCte.PedirServicio(ptrMsg1,iErrorLong,ptrobjParametros>pstrDatosSalida,(long *)&ptrobjParametros->tamSalida ); //fprintf(stream,"Trama respuesta: %s\n",ptrobjParametros>pstrDatosSalida);

- 106 -

//fprintf(stream,"Tam Trama respuesta: %i\n",ptrobjParametros>tamSalida); if( (stream = fopen(strNameFile , "a+" )) == NULL ) AfxMessageBox(_T("Error al abrir archivo log*.txt...") ,MB_OK); //*************************** //Fin de Retrasmitir la informacion a la IP de Host //** //devolvemos los resultados a la maquina Cliente Original. iErrorLong=0; if ((iErrorLong=send(ptrobjParametros->SockProc,ptrobjParametros>pstrDatosSalida ,ptrobjParametros->tamSalida,0)) < 0) { fprintf(stream,"Error de send de Servidor a Cte...: %i\n",iErrorLong); fclose(stream); //AfxMessageBox(_T("Error de send de Servidor a Cte...") ,MB_OK); } fclose(stream); //damos por terminada la comunicación. closesocket(ptrobjParametros->SockProc); delete ptrobjParametros; return 0; } CServidor::~CServidor() { //destruir la conexion si sigue activa y hacer limpieza closesocket(sock); }

//recibe en bufdatos como maximo maxdatos (si hay mas retorna error) int CServidor::servicio(char *bufdatosIn, char *bufdatosOut, long maxdatosInOut, long &datosleidos,long &datosenviados, int timeout, CParametros parametros) { //Primero se construye la estructura de timeouts //Un conjunto de sockets a comprobar si tienen peticiones fd_set set; FD_ZERO(&set); FD_SET(sock,&set); //...y el tiempo máximo a esperar si hay buffer de entrada struct timeval tval; tval.tv_sec=10; tval.tv_usec=timeout; //se suspende la ejecución hasta que haya petición o //se cumpla el tiempo de espera //se modifico para validar el tiempo de espera a indefinido. int result=select(0,&set,0,0,NULL); //int result=select(0,&set,0,0,&tval); if(result==0) return ETIMEOUT; //retornar si cumple tiempo espera //hay petición y se procesa. int sockacept=accept(sock,(struct sockaddr *) &addr, (int *) &lenaddr );

- 107 -

if(sockacept==-1) { AfxMessageBox(_T("Error de accept...") ,MB_OK); return EACCEPT; } //throw("Error en accept"); //obtenemos datos del socket creado por el sitema para atender //el servicio /* int lenaddrservicio= sizeof addr; if( getsockname( sockacept, (struct sockaddr *) &addrservicio, &lenaddrservicio ) ==-1) throw("Error averiguando sockaddr_in del socket asignado para el servicio"); int lenaddrcliente= sizeof addrcliente; if( getpeername( sockacept, (struct sockaddr *) &addrcliente, &lenaddrcliente ) ==-1) throw("Error averiguando sockaddr_in del socket cliente conectado a este"); */ //printf("Socket port #%d\n", ntohs( server.sin_port)); //Con los datos del cliente se podría decidor si se acepta o no //la petición... //Se reciben los datos. //retval=recv(sockacept,bufdatosIn,maxdatosInOut,0); //if (retval==-1) // throw("Error en recv"); //xxdatosleidos=retval; //char cadena[32000]="";

CParametros *ptrObjParam= new CParametros; ptrObjParam->SockProc=sockacept; ptrObjParam->pstrDatosEntrada=bufdatosIn; ptrObjParam->maxDatosEntSal= maxdatosInOut ; ptrObjParam->pstrDatosSalida=bufdatosOut; ptrObjParam->m_ipHost =parametros.m_ipHost ; ptrObjParam->m_puertoHost= parametros.m_puertoHost ; /* CParametros *ptrObjParam= ¶metros; ptrObjParam->SockProc=sockacept; ptrObjParam->pstrDatosEntrada=bufdatosIn; ptrObjParam->maxDatosEntSal= maxdatosInOut ; ptrObjParam->pstrDatosSalida=bufdatosOut; */ //Modificacion para pruebas //CWinThread *pThr; //pThr=AfxBeginThread(ThreadSockProc,ptrObjParam); #pragma omp parallel {

- 108 -

//#pragma omp single //Ahi que cambiar el procedimiento y paso de parametros. AfxBeginThread(ThreadSockProc,ptrObjParam); }

//*************************** //Retrasmite la informacion a la IP de Host //CCliente objCte("150.50.102.15",3224); //objCte.PedirServicio(bufdatosIn,retval,bufdatosOut,&datosleidos);

//*************************** //Fin de Retrasmite la informacion a la IP de Host //devolvemos los resultados //if (send(sockacept,bufdatosOut,datosleidos,0) 1000 #pragma once #endif // _MSC_VER > 1000 #include #include #include #include



const int DefaultTTL=1; const const const const const const

int int int int int int

ERRBASE=65536; OK=0; ESEND = ERRBASE+1; ERECV = ERRBASE+2; ETIMEOUT = ERRBASE+3; EACCEPT = ERRBASE+4;

class Csockbase { public: struct sockaddr_in addr; int lenaddr; int sock; int err; int retval; Csockbase(); virtual ~Csockbase();

// dirección // longitud de la direccion // socket

}; #endif // !defined(AFX_SOCKBASE_H__9C4836F8_DA0A_4A10_B931_1724EAF90048__INCLUDED_)

// sockbase.cpp: implementation of the Csockbase class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "ServerTCP.h" #include "sockbase.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif

- 110 -

////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// Csockbase::Csockbase() { } Csockbase::~Csockbase() { }

// stdafx.h : include file for standard system include files, // or project specific include files that are used frequently, but // are changed infrequently // #if !defined(AFX_STDAFX_H__21013768_D8C6_4A23_9000_9DF0CC1E49B2__INCLUDED_) #define AFX_STDAFX_H__21013768_D8C6_4A23_9000_9DF0CC1E49B2__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #define VC_EXTRALEAN headers

// Exclude rarely-used stuff from Windows

#include // MFC core and standard components #include // MFC extensions #include // MFC Automation classes #include // MFC support for Internet Explorer 4 Common Controls #ifndef _AFX_NO_AFXCMN_SUPPORT #include // MFC support for Windows Common Controls #endif // _AFX_NO_AFXCMN_SUPPORT #include

// MFC socket extensions

// This macro is the same as IMPLEMENT_OLECREATE, except it passes TRUE // for the bMultiInstance parameter to the COleObjectFactory constructor. // We want a separate instance of this application to be launched for // each automation proxy object requested by automation controllers. #ifndef IMPLEMENT_OLECREATE2 #define IMPLEMENT_OLECREATE2(class_name, external_name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ AFX_DATADEF COleObjectFactory class_name::factory(class_name::guid, \ RUNTIME_CLASS(class_name), TRUE, _T(external_name)); \ const AFX_DATADEF GUID class_name::guid = \ { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }; #endif // IMPLEMENT_OLECREATE2

- 111 -

//{{AFX_INSERT_LOCATION}} // Microsoft Visual C++ will insert additional declarations immediately before the previous line. #endif // !defined(AFX_STDAFX_H__21013768_D8C6_4A23_9000_9DF0CC1E49B2__INCLUDED_)

// stdafx.cpp : source file that includes just the standard includes // ServerTCP.pch will be the pre-compiled header // stdafx.obj will contain the pre-compiled type information #include "stdafx.h"

- 112 -

Fuentes del código de encripción TDESIVR.h /** HYGATSJ **********************************************************************************/ // // // // // //

The following ifdef block is the standard way of creating macros which make exporting from a DLL simpler. All files within this DLL are compiled with the TDESIVR_EXPORTS symbol defined on the command line. this symbol should not be defined on any project that uses this DLL. This way any other project whose source files include this file see TDESIVR_API functions as being imported from a DLL, wheras this DLL sees symbols defined with this macro as being exported.

#ifdef TDESIVR_EXPORTS #define TDESIVR_API __declspec(dllexport) #else #define TDESIVR_API __declspec(dllimport) #endif

TDESIVR_API long IVRCipher(IQVAL line, PUSERDLLPARAM32 InputMsg, PUSERDLLPARAM32 OutputMsg, PUSERDLLPARAM32 Servicio); TDESIVR_API long TDESCipher(char *InputMsg, char *OutputMsg, int *MsgLen, char *Servicio, int *OutMsgLen); long __stdcall VBCipher(char *InputMsg, char *OutputMsg, int *MsgLen, char *Servicio); /** Fin del header TDESIVR.h *****************************************************************/

- 113 -

TDESIVR.cpp // TDESIVR.cpp : Defines the entry point for the DLL application. // #include #define #include #include

"StdAfx.h" TDESIVR_EXPORTS "TDESIVR.h" "CnvBase64.h"

BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { return TRUE; } /******************************************************************************************* ****/ IQCOMPATIBLE (IQLEVEL_COMPATIBLE) /** HYGATSJ **********************************************************************************/ /** Area de redefiniciones *******************************************************************/ union Vector_Type { unsigned char Vector_Chr[4]; unsigned int Vector_Int; }; /** Area de estructuras **********************************************************************/ struct find_a_bit { int which_Byte; int which_bit; }; struct key_type { unsigned char KeyVal[6]; }; struct s_type { unsigned char s_val[4][16]; }; struct { int int int int };

s_RowBit_Type

struct { int int int int

s_ColBit_Type

s_RowByte_H; s_RowBit_H; s_RowByte_L; s_RowBit_L;

s_ColByte_1; s_ColBit_1; s_ColByte_2; s_ColBit_2;

- 114 -

int int int int

s_ColByte_3; s_ColBit_3; s_ColByte_4; s_ColBit_4;

}; /** Area de definición de constantes *********************************************************/ static struct find_a_bit IP_L0 [32] = {{07,01},{06,01},{05,01},{04,01},{03,01},{02,01},{01,01},{00,01}, {07,03},{06,03},{05,03},{04,03},{03,03},{02,03},{01,03},{00,03}, {07,05},{06,05},{05,05},{04,05},{03,05},{02,05},{01,05},{00,05}, {07,07},{06,07},{05,07},{04,07},{03,07},{02,07},{01,07},{00,07}}; static struct find_a_bit IP_R0 [32] = {{07,00},{06,00},{05,00},{04,00},{03,00},{02,00},{01,00},{00,00}, {07,02},{06,02},{05,02},{04,02},{03,02},{02,02},{01,02},{00,02}, {07,04},{06,04},{05,04},{04,04},{03,04},{02,04},{01,04},{00,04}, {07,06},{06,06},{05,06},{04,06},{03,06},{02,06},{01,06},{00,06}}; static struct find_a_bit E [48] = {{03,07},{00,00},{00,01},{00,02},{00,03},{00,04},{00,03},{00,04}, {00,05},{00,06},{00,07},{01,00},{00,07},{01,00},{01,01},{01,02}, {01,03},{01,04},{01,03},{01,04},{01,05},{01,06},{01,07},{02,00}, {01,07},{02,00},{02,01},{02,02},{02,03},{02,04},{02,03},{02,04}, {02,05},{02,06},{02,07},{03,00},{02,07},{03,00},{03,01},{03,02}, {03,03},{03,04},{03,03},{03,04},{03,05},{03,06},{03,07},{00,00}}; static struct find_a_bit P [32] = {{01,07},{00,06},{02,03},{02,04},{03,04},{01,03},{03,03},{02,00}, {00,00},{01,06},{02,06},{03,01},{00,04},{02,01},{03,06},{01,01}, {00,01},{00,07},{02,07},{01,05},{03,07},{03,02},{00,02},{01,00}, {02,02},{01,04},{03,05},{00,05},{02,05},{01,02},{00,03},{03,00}}; static struct find_a_bit PC_Inv [64] = {{04,07},{00,07},{05,07},{01,07},{06,07},{02,07},{07,07},{03,07}, {04,06},{00,06},{05,06},{01,06},{06,06},{02,06},{07,06},{03,06}, {04,05},{00,05},{05,05},{01,05},{06,05},{02,05},{07,05},{03,05}, {04,04},{00,04},{05,04},{01,04},{06,04},{02,04},{07,04},{03,04}, {04,03},{00,03},{05,03},{01,03},{06,03},{02,03},{07,03},{03,03}, {04,02},{00,02},{05,02},{01,02},{06,02},{02,02},{07,02},{03,02}, {04,01},{00,01},{05,01},{01,01},{06,01},{02,01},{07,01},{03,01}, {04,00},{00,00},{05,00},{01,00},{06,00},{02,00},{07,00},{03,00}}; static struct s_type s_function [8] = {0xE0,0x40,0xD0,0x10,0x20,0xF0,0xB0,0x80,0x30,0xA0,0x60,0xC0,0x50,0x90,0x00,0x70, 0x00,0xF0,0x70,0x40,0xE0,0x20,0xD0,0x10,0xA0,0x60,0xC0,0xB0,0x90,0x50,0x30,0x80,

- 115 -

0x40,0x10,0xE0,0x80,0xD0,0x60,0x20,0xB0,0xF0,0xC0,0x90,0x70,0x30,0xA0,0x50,0x00, 0xF0,0xC0,0x80,0x20,0x40,0x90,0x10,0x70,0x50,0xB0,0x30,0xE0,0xA0,0x00,0x60,0xD0,

0x0F,0x01,0x08,0x0E,0x06,0x0B,0x03,0x04,0x09,0x07,0x02,0x0D,0x0C,0x00,0x05,0x0A, 0x03,0x0D,0x04,0x07,0x0F,0x02,0x08,0x0E,0x0C,0x00,0x01,0x0A,0x06,0x09,0x0B,0x05, 0x00,0x0E,0x07,0x0B,0x0A,0x04,0x0D,0x01,0x05,0x08,0x0C,0x06,0x09,0x03,0x02,0x0F, 0x0D,0x08,0x0A,0x01,0x03,0x0F,0x04,0x02,0x0B,0x06,0x07,0x0C,0x00,0x05,0x0E,0x09,

0xA0,0x00,0x90,0xE0,0x60,0x30,0xF0,0x50,0x10,0xD0,0xC0,0x70,0xB0,0x40,0x20,0x80, 0xD0,0x70,0x00,0x90,0x30,0x40,0x60,0xA0,0x20,0x80,0x50,0xE0,0xC0,0xB0,0xF0,0x10, 0xD0,0x60,0x40,0x90,0x80,0xF0,0x30,0x00,0xB0,0x10,0x20,0xC0,0x50,0xA0,0xE0,0x70, 0x10,0xA0,0xD0,0x00,0x60,0x90,0x80,0x70,0x40,0xF0,0xE0,0x30,0xB0,0x50,0x20,0xC0,

0x07,0x0D,0x0E,0x03,0x00,0x06,0x09,0x0A,0x01,0x02,0x08,0x05,0x0B,0x0C,0x04,0x0F, 0x0D,0x08,0x0B,0x05,0x06,0x0F,0x00,0x03,0x04,0x07,0x02,0x0C,0x01,0x0A,0x0E,0x09, 0x0A,0x06,0x09,0x00,0x0C,0x0B,0x07,0x0D,0x0F,0x01,0x03,0x0E,0x05,0x02,0x08,0x04, 0x03,0x0F,0x00,0x06,0x0A,0x01,0x0D,0x08,0x09,0x04,0x05,0x0B,0x0C,0x07,0x02,0x0E,

0x20,0xC0,0x40,0x10,0x70,0xA0,0xB0,0x60,0x80,0x50,0x30,0xF0,0xD0,0x00,0xE0,0x90, 0xE0,0xB0,0x20,0xC0,0x40,0x70,0xD0,0x10,0x50,0x00,0xF0,0xA0,0x30,0x90,0x80,0x60, 0x40,0x20,0x10,0xB0,0xA0,0xD0,0x70,0x80,0xF0,0x90,0xC0,0x50,0x60,0x30,0x00,0xE0, 0xB0,0x80,0xC0,0x70,0x10,0xE0,0x20,0xD0,0x60,0xF0,0x00,0x90,0xA0,0x40,0x50,0x30,

0x0C,0x01,0x0A,0x0F,0x09,0x02,0x06,0x08,0x00,0x0D,0x03,0x04,0x0E,0x07,0x05,0x0B, 0x0A,0x0F,0x04,0x02,0x07,0x0C,0x09,0x05,0x06,0x01,0x0D,0x0E,0x00,0x0B,0x03,0x08, 0x09,0x0E,0x0F,0x05,0x02,0x08,0x0C,0x03,0x07,0x00,0x04,0x0A,0x01,0x0D,0x0B,0x06, 0x04,0x03,0x02,0x0C,0x09,0x05,0x0F,0x0A,0x0B,0x0E,0x01,0x07,0x06,0x00,0x08,0x0D,

0x40,0xB0,0x20,0xE0,0xF0,0x00,0x80,0xD0,0x30,0xC0,0x90,0x70,0x50,0xA0,0x60,0x10, 0xD0,0x00,0xB0,0x70,0x40,0x90,0x10,0xA0,0xE0,0x30,0x50,0xC0,0x20,0xF0,0x80,0x60, 0x10,0x40,0xB0,0xD0,0xC0,0x30,0x70,0xE0,0xA0,0xF0,0x60,0x80,0x00,0x50,0x90,0x20, 0x60,0xB0,0xD0,0x80,0x10,0x40,0xA0,0x70,0x90,0x50,0x00,0xF0,0xE0,0x20,0x30,0xC0,

0x0D,0x02,0x08,0x04,0x06,0x0F,0x0B,0x01,0x0A,0x09,0x03,0x0E,0x05,0x00,0x0C,0x07, 0x01,0x0F,0x0D,0x08,0x0A,0x03,0x07,0x04,0x0C,0x05,0x06,0x0B,0x00,0x0E,0x09,0x02, 0x07,0x0B,0x04,0x01,0x09,0x0C,0x0E,0x02,0x00,0x06,0x0A,0x0D,0x0F,0x03,0x05,0x08, 0x02,0x01,0x0E,0x07,0x04,0x0A,0x08,0x0D,0x0F,0x0C,0x09,0x00,0x03,0x05,0x06,0x0B}; static unsigned char SKE[3] = {'S','K','E'}; static struct key_type TDES_Key[48] = {0x27,0xE4,0x8A,0xDB,0xFF,0xC6,

- 116 -

0xD4,0x33,0xCD,0x5D,0xBB,0x2F, 0x13,0xDE,0x61,0xB6,0x7C,0xFC, 0xC9,0x79,0xE6,0x69,0xBB,0xF7, 0xB0,0xE7,0xCD,0xB7,0xEC,0xBB, 0x51,0x57,0x23,0x6F,0x1F,0x57, 0xE1,0x99,0xF5,0x9F,0xE1,0xFE, 0x95,0xE2,0xC7,0x65,0xDF,0xC5, 0xEC,0x0F,0x5E,0x7E,0xBA,0xD8, 0x66,0xFA,0x09,0xF1,0xF5,0x7F, 0x0B,0xBD,0x72,0x2F,0xBE,0xAA, 0xEC,0x6C,0xDB,0xFC,0x7D,0x77, 0x77,0xE7,0x08,0x2F,0xCA,0xFE, 0x4A,0x9D,0x93,0xD5,0xFD,0xD3, 0x7D,0xA8,0x5F,0xAF,0x86,0x7D, 0x89,0x5F,0xBC,0xF3,0x56,0xFA, 0xB7,0x0D,0x92,0x46,0x4A,0xFB, 0x9C,0xD7,0x4C,0x2F,0xE9,0x64, 0xCA,0x72,0xF8,0x1E,0x75,0x73, 0x9F,0x1E,0x60,0x3F,0x9E,0x8B, 0xA6,0x32,0xB5,0xF0,0xA6,0xFF, 0x85,0x0B,0x3E,0xE4,0xBA,0xC4, 0xB8,0xC0,0x35,0x95,0x61,0x6E, 0x72,0x01,0xEE,0x7F,0x53,0x12, 0xC5,0x3F,0x08,0xA3,0x1F,0x67, 0xA8,0x6E,0x3D,0xA7,0xF0,0xB9, 0x8A,0x29,0x6A,0x49,0x78,0xDF, 0x3E,0xD8,0x2C,0x7C,0x4C,0xBC, 0x4E,0x02,0xDE,0x59,0xBF,0x26, 0x9F,0x94,0x1C,0xA3,0x97,0x78, 0x7E,0x22,0xB1,0xD7,0xB9,0x59, 0x42,0x5B,0x4B,0xE0,0xED,0xD2, 0x6F,0x10,0xA7,0x6A,0x58,0x3E, 0x09,0xB7,0x29,0x8A,0xCD,0xB2, 0xC1,0x1C,0xDB,0x8D,0x6F,0x11, 0x75,0xEA,0xC0,0xFB,0x42,0x50, 0x12,0xFD,0x82,0xD1,0xC3,0x0E, 0x78,0x25,0x57,0x94,0x36,0x8C, 0x65,0xC4,0x0D,0xF8,0x32,0xE5, 0x43,0x81,0xB6,0x32,0xEA,0xAB, 0xD2,0xC6,0x69,0x22,0x6D,0x8F, 0xC9,0xDB,0x02,0xAE,0x11,0x97, 0x20,0xBB,0xCF,0xC7,0x43,0xE3, 0x31,0x74,0x43,0x56,0x8B,0x49, 0x61,0x4D,0xF0,0xD2,0x95,0x5C, 0xD4,0xE1,0x95,0x49,0xB7,0xA8, 0x17,0x87,0x13,0x78,0x7C,0x29, 0xEA,0x6B,0x09,0x3A,0xDC,0x65}; static unsigned char SKD[3] = {'S','K','D'}; static struct key_type unTDES_Key[48] = {0xEA,0x6B,0x09,0x3A,0xDC,0x65, 0x17,0x87,0x13,0x78,0x7C,0x29, 0xD4,0xE1,0x95,0x49,0xB7,0xA8, 0x61,0x4D,0xF0,0xD2,0x95,0x5C, 0x31,0x74,0x43,0x56,0x8B,0x49, 0x20,0xBB,0xCF,0xC7,0x43,0xE3, 0xC9,0xDB,0x02,0xAE,0x11,0x97, 0xD2,0xC6,0x69,0x22,0x6D,0x8F, 0x43,0x81,0xB6,0x32,0xEA,0xAB, 0x65,0xC4,0x0D,0xF8,0x32,0xE5, 0x78,0x25,0x57,0x94,0x36,0x8C, 0x12,0xFD,0x82,0xD1,0xC3,0x0E, 0x75,0xEA,0xC0,0xFB,0x42,0x50, 0xC1,0x1C,0xDB,0x8D,0x6F,0x11, 0x09,0xB7,0x29,0x8A,0xCD,0xB2, 0x6F,0x10,0xA7,0x6A,0x58,0x3E, 0x42,0x5B,0x4B,0xE0,0xED,0xD2, 0x7E,0x22,0xB1,0xD7,0xB9,0x59, 0x9F,0x94,0x1C,0xA3,0x97,0x78, 0x4E,0x02,0xDE,0x59,0xBF,0x26, 0x3E,0xD8,0x2C,0x7C,0x4C,0xBC,

- 117 -

0x8A,0x29,0x6A,0x49,0x78,0xDF, 0xA8,0x6E,0x3D,0xA7,0xF0,0xB9, 0xC5,0x3F,0x08,0xA3,0x1F,0x67, 0x72,0x01,0xEE,0x7F,0x53,0x12, 0xB8,0xC0,0x35,0x95,0x61,0x6E, 0x85,0x0B,0x3E,0xE4,0xBA,0xC4, 0xA6,0x32,0xB5,0xF0,0xA6,0xFF, 0x9F,0x1E,0x60,0x3F,0x9E,0x8B, 0xCA,0x72,0xF8,0x1E,0x75,0x73, 0x9C,0xD7,0x4C,0x2F,0xE9,0x64, 0xB7,0x0D,0x92,0x46,0x4A,0xFB, 0x89,0x5F,0xBC,0xF3,0x56,0xFA, 0x7D,0xA8,0x5F,0xAF,0x86,0x7D, 0x4A,0x9D,0x93,0xD5,0xFD,0xD3, 0x77,0xE7,0x08,0x2F,0xCA,0xFE, 0xEC,0x6C,0xDB,0xFC,0x7D,0x77, 0x0B,0xBD,0x72,0x2F,0xBE,0xAA, 0x66,0xFA,0x09,0xF1,0xF5,0x7F, 0xEC,0x0F,0x5E,0x7E,0xBA,0xD8, 0x95,0xE2,0xC7,0x65,0xDF,0xC5, 0xE1,0x99,0xF5,0x9F,0xE1,0xFE, 0x51,0x57,0x23,0x6F,0x1F,0x57, 0xB0,0xE7,0xCD,0xB7,0xEC,0xBB, 0xC9,0x79,0xE6,0x69,0xBB,0xF7, 0x13,0xDE,0x61,0xB6,0x7C,0xFC, 0xD4,0x33,0xCD,0x5D,0xBB,0x2F, 0x27,0xE4,0x8A,0xDB,0xFF,0xC6}; static struct s_RowBit_Type Row2Use[8] = {0,0,0,5, 0,6,1,3, 1,4,2,1, 2,2,2,7, 3,0,3,5, 3,6,4,3, 4,4,5,1, 5,2,5,7}; static struct s_ColBit_Type Col2Use[8] = {0,1,0,2,0,3,0,4, 0,7,1,0,1,1,1,2, 1,5,1,6,1,7,2,0, 2,3,2,4,2,5,2,6, 3,1,3,2,3,3,3,4, 3,7,4,0,4,1,4,2, 4,5,4,6,4,7,5,0, 5,3,5,4,5,5,5,6}; static unsigned int Ask4Bit[8] = {128,64,32,16,8,4,2,1}; static unsigned int Set_Bit[8] = {128,64,32,16,8,4,2,1}; static unsigned int Clear_Bit[8] = {127,191,223,239,247,251,253,254}; static unsigned int Shifts[16] = {1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1}; static char Low_Values[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; /** Area de definición de funciones **********************************************************/ void Permuta(char *Ini_Vector, struct find_a_bit *Perm_Arr, char *Vector_Fin, int PosIni, int PosFin, int SizeOut); void ExOr(char *Vector_A, char *Vector_B, char *Vector_C, int BlqSize);

- 118 -

unsigned int GetRow(char *Vector, int S_Grp); unsigned int GetCol(char *Vector, int S_Grp); void S_Func(char *Vector_Xor, char *Vector_S); void ExecTDES (char *pInputMsg, char *pOutputMsg, int MsgSize, char Servicio, char *IniCBC); int ProcTDES(char *InputMsg, char *OutPutMsg, int MsgSize, char Servicio); void Base256a64(char *OutTDES, char *OutPutMsg, int *finalsize); void Base64a256(char *InputMsg, char *OutTDES, int *finalsize); /** Permutacion: A partir de Ini_Vector generar Vector_Fin con las reglas de Perm_Arr ********/ void Permuta(char *Ini_Vector, struct find_a_bit *Perm_Arr, char *Vector_Fin, int PosIni, int PosFin, int SizeOut) { int Bit2Chk, Byte2Set, Bit2Set; for (Byte2Set = 0;Byte2Set < SizeOut;Byte2Set++) { Vector_Fin[Byte2Set] = 0x00; }; for (Bit2Chk = PosIni; Bit2Chk < PosFin; Bit2Chk++) { if(((unsigned int) Ini_Vector[Perm_Arr[Bit2Chk].which_Byte] & Ask4Bit[Perm_Arr[Bit2Chk].which_bit]) != 0) { Byte2Set = Bit2Chk / 8; Bit2Set = Bit2Chk % 8; Vector_Fin[Byte2Set] = Vector_Fin[Byte2Set] | Set_Bit[Bit2Set]; }; }; return; }; /** Vector_C = Vector_A Xor Vector_B *********************************************************/ void ExOr(char *Vector_A, char *Vector_B, char *Vector_C, int BlqSize) { int Byte2Proc; for (Byte2Proc=0;Byte2Proc> 1)] | s_function[S_In_Prc].s_val[Row2Proc][Col2Proc]; }; return; }; /** Ejecuta el cifrado / descifrado de información independiente al medio de entrada *********/ void ExecTDES (char *pInputMsg, char *pOutputMsg, int MsgSize, char Servicio, char *IniCBC) { struct key_type *KeyGen; char Wrk_Key[6]; char *info2TDES; int infolength; char *cbc_vec; char accion; char char char char

blk2Proc[8]; Vector_S[6]; Vector_Xor[8]; *blkTDES;

char char char char char

Vector_L[4]; Vector_R[4]; Vector_E[6]; Vector_P[4]; full_vector[8];

int int int int int

numblks; blk_num; TDES_In_Proc; sub_key; i;

cbc_vec = IniCBC; infolength = MsgSize; info2TDES = pInputMsg; blkTDES = pOutputMsg; accion = Servicio; numblks = infolength / 8; for (blk_num=0;blk_num