[perl] Retomando lo de mi proyecto y los dos sockets
Gunnar Wolf
gwolf@campus.iztacala.unam.mx
Wed, 14 Jun 2000 22:33:02 -0500 (CDT)
Hola de nuevo a todos.
Hace tiempo no le he dado a mi proyecto, y me estoy tardando bastante...
Pero bueno, el avance ahi va. Estoy atorado ahora con algo mas -y cada
vez, desafortunadamente, con cosas que parecen mas esotericas, y que
escapan con mucho mas a mi capacidad de entendimiento.
Primero que nada, dado el tiempo que no daba lata con esto, les repito por
encimita mi proyecto, aunque esta mucho mejor descrito en
http://www.gwolf.cx/wrap - Quiero crear un programita que me permita
envolver transparentemente una conexion de red TCP de cualquier protocolo
que cumpla ciertas caracteristicas para hacer mas segura la comunicacion
con el servidor, previniendo que pasen determinados comandos, secuencias o
longitudes de texto, comandos fuera de orden, o basicamente cualquier cosa
que pueda llevar a un comportamiento no deseado por parte del servidor. La
vez anterior que acudi a su ayuda fue porque no podia leer de dos sockets
diferentes a la vez... Bueno, esto lo pude hacer finalmente gracias a que
Salvador Ortiz me presento al maravilloso mundo del select sobre vectores.
Bueno, ahi va el fragmento relevante de codigo en su estado actual,
seguido de otro par de penares:
---------------------------
sub startServer {
my $child;
$listSock=IO::Socket::INET->new(LocalPort => $_[0],
Type => SOCK_STREAM,
Reuse => 1,
Listen => 10) or die "Couldn't be a TCP server on port ".$_[0]."\n";
die "Can't fork!: $@" if (!defined ($child=fork()));
if ($child == 0) {
# Child process - start server and start endless loop
getConn();
exit 0;
} else {
# Parent process - get back to the main program
close $listSock;
return $child;
}
}
sub getConn {
my ($client,$line,$src_conn,$src_port,$src_iaddr,$src_ip_address,$testok,$read_handles,$readable,$sock);
while ($client = $listSock->accept()) {
$src_conn=getpeername($client);
($src_port,$src_iaddr)=unpack_sockaddr_in($src_conn);
$src_ip_address=inet_ntoa($src_iaddr);
print "Connection recieved from $src_ip_address, source port $src_port\n";
$server=IO::Socket::INET->new(PeerAddr=>$destAddr,
PeerPort=>$destPort,
Proto=>"tcp",
Type=>SOCK_STREAM)
or die "$! - $@";
# IO::Select allows us to listen to many different filehandles (in this case,
# sockets) at once. We will listen to $client and $server.
$read_handles=new IO::Select();
$read_handles->add($client);
$read_handles->add($server);
while (1) {
($readable) = IO::Select->select($read_handles,undef,undef,0);
foreach $sock (@$readable) {
exit 0 if $sock->eof;
print join(', ',@$readable),"\n";
if ($sock == $client) {
$line = $client->getline;
$line =~ s/\r|\n//g;
$testok=testLine(\$line);
$server->print("$line\n");# if ($testok);
# print "CLIENT: $line";
} elsif ($sock == $server) {
$line=$server->getline;
$client->print($line);
# print "SERVER: $line";
}
}
}
close $client;
close $server;
print "Closing communication with $src_ip_address:$src_port\n";
}
}
---------------------------
Notaran que en getConn hay un while (1) {....} - Obviamente, esto no debe
quedar asi... Necesito encontrar una manera en que pueda decirle -sin leer
nada ni del socket que viene del cliente ni del que viene del servidor,
pues me quedaria atorado- que salga del ciclo cuando alguno de los sockets
se cierre. Se me ocurrio en este momento, de la misma manera que reviso en
$readable si puedo leer datos de alguno de los sockets, revisar si estan
listos para que les escriba algo. Si si, significa que no estan cerrados
todavia. Funcionaria mi estrategia? Seria algo como:
($writable) = IO::Select->select(undef,$read_handles,undef,0);
Despues, comparar con cada elemento de @$readable buscando tanto $server
como $client, y si alguno de ellos no esta presente, salir de la
funcion... Gusta?
Algo que tambien quiero hacer es reemplazar los $line=$sock->getline por
una subrutinita que me permita ir recibiendo un caracter por vez, para que
el wrapper no se quede trabado escuchando al cliente o al servidor si
estos han mandado solo un par de caracteres y no una linea completa...
Esto creo que seria con una rutinita que fuera construyendo la palabra
completa a base de $sock->getc, y enviara la linea tras analizarla y
probar su validez en caso de haber recibido un \n
En fin, ahi va... Les agradezco cualquier comentario que puedan hacerme.
En este momento todavia no estoy manejando bien el fork, pero es lo de
menos... Me interesa sacar la parte central.
Bueno, nos vemos!
-------------------------------------------------------------------
Gunnar Wolf gwolf@campus.iztacala.unam.mx
Universidad Nacional Autónoma de México, Campus Iztacala
Jefatura de Sección de Desarrollo y Admon. de Sistemas en Red
Area de Seguridad en Computo - DCI - DGSCA - UNAM
-------------------------------------------------------------------
Beginner thinks 1Kb == 1000 bytes. Master knows 1Km == 1024m
--------- Pie de mensaje --------------------------------
Visite: http://tlali.iztacala.unam.mx/~randrade/perl.shtml
Cancelar inscripcion:
mail to: majordomo@tlali.iztacala.unam.mx
text : unsubscribe perl