[INFO]: Kernel 2.2.x, glibce 2.2, getnameinfo()

Arkadiusz Miskiewicz misiek w pld.ORG.PL
Pią, 17 Lis 2000, 17:27:33 CET


No więc sytuacja wygląda tak:

Minimalne jądro, które należy posiadać by móc przejść na glibce2.2
to 2.2.17. Radzę nie próbować ze starszymi bo może takiego delikwenta
spotkać niespodzianka typu:

[misiek w ikar misiek]$ ./glibc22-jajco22test (statycznie linkowany)
FATAL: kernel too old
Przerwane
[misiek w ikar misiek]$ uname -r
2.2.16

Jeśli chodzi o kwestie związane z IPv6 to minimalna wersja oficjalne
supportowanego jaja to:

2.2.x	- dla glibców 2.1.x
2.3.99	- dla glibców 2.2

Osoby, które chcą używać jaja 2.2.x i glibców 2.2 mają dwa wyjścia:
a) zapomnieć o IPv6 i *wogóle nie kompilować go w jajo ani moduł*.
   Wtedy będzie wszystko bezproblemowo chodziło.
b) nadal używać IPv6 po uwcześniejszym zapatchowaniu jaja poniższym
   patchem (który wkrótce trafi do dystrybucyjnego kernela 2.2.x)
   
diff -urN linux-2.2.x.org/include/linux/in6.h linux-2.2.x/include/linux/in6.h
--- linux-2.2.x.org/include/linux/in6.h	Fri Nov 17 18:21:58 2000
+++ linux-2.2.x/include/linux/in6.h	Fri Nov 17 18:22:26 2000
@@ -56,6 +56,7 @@
 	__u16			sin6_port;      /* Transport layer port # */
 	__u32			sin6_flowinfo;  /* IPv6 flow information */
 	struct in6_addr		sin6_addr;      /* IPv6 address */
+	__u32			sin6_scope_id;	/* scope id (new in RFC2553) */
 };

(wszystko po to, żeby rozmiar strucktury sockaddr_in6 w jądrze linuksa
 == rozmiarowi struktury sockaddr_in6 w glibcach 2.2).

Tak zapatchowane jajo powinno bez problemów działać również na glibcach 2.1.x
ale nie testowałem tego jako, że ani nie używam jaj 2.2.x ani glibców 2.1.x :>

Powyższy patch pozwoli uniknąć kłopotów typu:
sshd:  fatal: get_sock_port: getnameinfo NI_NUMERICSERV failed

Jakieś pytania/uwagi ?

ps. kloczek/baggins -- wrzućcie tego patcha do dystrybucyjnego jaja
    jak będziecie coś w nim grzebać.
    
ps2. w attachu znajduje się mały, badziwewny programik do sprawdzania
czy jajo będzie działało ok z glibcami 2.2 i IPv6. Wywołuje się go
z adresem ipv6 maszyny, na której działa byle jakie sshd (może się
łączyć z dowolną inna usługą ipv6 -- to nie ma znaczenia -- trzeba tylko
w źródełku port zmienić):

[misiek w arm 3]$ ./glibc22-jajco22test ::1
Resolving ... ::1
Socket: 3
Size1: 128
Size2: 28
Size3: 28
Size4: 28
Konekszyn z ipv6-localhost [::1]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ To oraz te same wartości przy size2, size3 i size4
                                 oznacza, że jajo jest ok.
[misiek w arm 3]$


-- 
Arkadiusz Miśkiewicz, AM2-6BONE    [ PLD GNU/Linux IPv6 ]
http://www.t17.ds.pwr.wroc.pl/~misiek/ipv6/   [ enabled ]
-------------- następna część ---------
/*
   Copyright (C) 1999, 2000 Arkadiusz Miśkiewicz <misiek w pld.org.pl>
   Ten kod nie nadaje sie do uzytku ;) To tylko do testowania sluzy.
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <netinet/in.h>
#include <netdb.h>

int main(int argc,char *argv[])
{

  struct addrinfo hints, *ai, *aitop;
  int gaierr, st;
  char addr[NI_MAXHOST], addrip[NI_MAXHOST];
 
  if (argc <= 1 || argc > 2) {
	  fprintf(stderr, "Usage:\t%s\t<host or ip addr>\n", argv[0]);
	  exit(1);
  }
	  
  memset(&hints, 0, sizeof(hints));
  hints.ai_family = AF_UNSPEC;
  hints.ai_socktype = SOCK_STREAM;
  fprintf(stdout, "Resolving ... %s\n", argv[1]);
  if (!(gaierr = getaddrinfo(argv[1], "22", &hints, &aitop)))
  {
	  for (ai = aitop; ai; ai = ai->ai_next) {
		  st = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
		  if (st < 0) {
		      printf("Socket siet ;)\n");
		      continue;
		  }
		  if (connect(st, ai->ai_addr, ai->ai_addrlen) < 0) {
		      printf("Connect siet ;)\n");
		      close(st);
		      continue;
		  }
		  printf("Socket: %d\n", st);
		  {
			  struct sockaddr_storage s;
			  int ssize = sizeof(s);
			  int q;
			  memset(&s, 0, sizeof(s));
			  printf("Size1: %d\n", ssize);
			  if (getpeername(st, (struct sockaddr *)&s, &ssize)) {
			      printf("Getpeername siet ;)\n");
			      close(st);
			      continue;
			  }
			  if (s.__ss_family == AF_INET6)
			      memset(&((struct sockaddr_in6 *)&s)->sin6_scope_id, 0,
				      sizeof(((struct sockaddr_in6 *)&s)->sin6_scope_id));
			  printf("Size2: %d\n", ssize);
			  if ((q = getnameinfo((struct sockaddr *)&s, ssize,
					  addrip, sizeof(addrip), NULL, 0, NI_NUMERICHOST)))
				  printf("Problemiq1: %s\n", gai_strerror(q));
			  printf("Size3: %d\n", ssize);
			  if ((q = getnameinfo((struct sockaddr *)&s, ssize,
					  addr, sizeof(addr), NULL, 0, 0)))
				  printf("Problemiq2: %s\n", gai_strerror(q));
			  printf("Size4: %d\n", ssize);
		  }
		  if (st > 0)
		      fprintf(stdout, "Konekszyn z %s [%s]\n", addr, addrip);
		  close(st);
		  exit(0);
	  }
	  freeaddrinfo(aitop);
  } else {
	  fprintf(stdout, "Resolving ... %s\n", argv[1]);
	  exit(1);
  }
  exit(0);
}


Więcej informacji o liście dyskusyjnej pld-devel-pl