Nov 28

La maldición de las herramientas

web services internet Es bastante habitual que la gente que empieza a aprender java (o cualquier otro lenguaje de programación) coja el IDE correspondiente (eclipse, netbeans o el que sea)  y se ponga a aprender. Esos novatos van programando y con el tiempo van cogiendo ciertos conocimientos y experiencia en java. Pero desgraciadamente, el IDE les hace no aprender ciertas cosas básicas. No es raro encontrarse gente que lleva programando algún tiempo pero que sería incapaz de compilar o ejecutar un programa java desde línea de comandos, usando los comandos java, el compilador javac, o generar su jar con el comando jar.

Y esto no solo pasa con las cosas básicas ni sólo con los novatos. Cuanto más complejo sea el tema y más nos resuelva un IDE o una herramienta/framework cualquiera, menos cosas aprendemos de ese tema y más dependemos del IDE/herramienta/framework. Cuento mi caso de hace un par de días.

Llevo ya unos días trabajando con Web Services con jax-ws. Cuando empecé con ello, no me leí la documentación completa (soy un impaciente) y en seguida me puse a buscar ejemplos de aquí y de allí para ir haciendo mi propio código. Leí en la documentación que para hacer un Web Services bastaba con ponerle unas anotaciones a la clase (@WebService, @WebMethod, etc), compilarla de forma normal, pasarle la herramienta wsgen que viene con jax-ws y listo. Pues bien, eso hice, montando todo desde el principio con maven y plugins de maven. Y desde luego, pasando ese wsgen automáticamente en la fase posterior al compilado.

Hace un par de días me decidí a hacer un tutorial sobre la aprendido y quise hacerlo más de forma manual, dependiendo lo menos posible de herramientas (eclipse, maven, etc). Así que me puse a ello … y empezaron las dudas y a ponerse de manifiesto las grandes lagunas en mi conocimiento.

El problema desencadenante de todo es que hice todos los pasos para el tutorial sin usar la herramienta wsgen y el web service me funciona. Una clase con las anotaciones correspondientes, un main() que arranca un EndPoint, no se pasa el wsgen y funciona, arrancado desde línea de comandos.

Bueno, según la documentación, después de pasar el wsgen se hace el war para desplegarlo en Tomcat o similar. Será entonces que si usas EndPoint no necesitas pasar wsgen, quizás EndPoint hace todo eso que hace wsgen de forma automática. Pero lo grave de todo es que sí, se supone que hay que pasar wsgen, pero realmente no sé qué hace wsgen (sí lo sé, genera unos fuentes java que no sé exactamente para qué sirven).

Así que nada, seguiré de forma manual, intentaré montar el "hola mundo" en un tomcat y veré si ahí es necesario o no el wsgen… Y luego a pelearse con la parte del cliente, que aunque también la se hacer con herramientas, tampoco entiendo el fondo de todo.

Nov 24

Winpcap, jpcap y java

 En uno de los proyectos (java) tenía necesidad de tocar uno de los campos que hay en las cabeceras IP de los mensajes, en concreto, el campo de tipo de servicio, que de alguna forma establece prioridades para el mensaje.

Mirando la API de java, veo que la clase Socket tiene un método setTrafficClass() que de alguna manera sirve para cambiar este campo, pero fíjate tú que cosas, hago mis pruebas, arranco un sniffer (Wireshark gratuito) y de todos los bits de ese campo sólo consigo cambiar el segundo. Todos los demás bits siempre se captura con ceros. No es de extrañar, la misma API de java indica que ese método puede o no funcionar dependiendo del "underlying network implementation", así que empiezo a buscar librerías que me faciliten esto.

Al final, el conjunto de librerías a usar es Winpcap + jpcap. La primera es un instalable windows que nos proporciona unas librerías de base (dll) para programar sockets a bajo nivel. La segunda es una librería java que nos facilita las llamadas a la librería Winpcap. Con ambas juntas, podemos programar sockets a bajo nivel desde java con comodidad. Eso sí, hay JNI entre medias aunque no lo veamos al programar.

La aplicación típica que muestra en los ejemplos de esta librería jpcap es la captura de paquetes de red, para hacerse uno su propio sniffer. También permite el envío de paquetes IP, dando valores a todos los campos de la cabecera IP a nuestro gusto. Tras pelearme con ella un par de días, todo parece funcionar bien. Sin embargo, en esos días encontré pegas que ¿cómo no?, pongo aquí. No son pegas de la librería, sino del entorno. Allá van:

  1. Posiblemente se necesitan permisos de administrador para ejecutar nuestro programa si anda manejando las tarjetas de red con la librería jpcap.
  2. En Windows XP hay una variable de registro que debe tener un valor concreto para que nuestro programa tenga permisos para modificar el campo traffic class: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters : "DisableUserTOSSetting"=dword:00000000
  3. Cuando se envía un paquete IP, en el ejemplo pone unas direcciones mac "aleatorias". Para que funcione bien es importante poner direcciones mac correctas. La de origen puede tener o no importancia, dependiendo de si por debajo se nos permite o no enviar cabeceras IP con una mac propia falsa. La de destino debe ser correcta o el mensaje nunca llegará. Se puede poner 255:255:255:255:255:255 si la mac de destino es desconocida.
  4. La mayoría de los routers/switch de la red están configurados por defecto para poner a cero los campos del traffic class de la cabecera IP, por lo que aunque cambiemos esos campos, es muy posible que a destino lleguen como ceros. No es que no funcione la librería, sino que hay que configurar bien los routers/switches.
  5. Así que el sniffer que usemos para ver si todo va como debe, debemos arrancarlo tanto en el PC que envía como en el que recibe. En el que envía podemos ver si hemos rellenado todos los campos como queremos. En el que recibe veremos si ningún router malvado lo ha modificado por el camino.

En fin, que he estado entretenido un par de días.