Changeset 100
- Timestamp:
- 07/03/07 19:48:26 (1 year ago)
- Files:
-
- trunk/connect.c (modified) (12 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/connect.c
r99 r100 530 530 } 531 531 532 void 533 downcase( char *buf ) 534 { 532 char * 533 downcase( char *str ) 534 { 535 char *buf = str; 535 536 while ( *buf ) { 536 537 if ( isupper(*buf) ) … … 538 539 buf++; 539 540 } 541 return str; /* return converted arg */ 540 542 } 541 543 … … 790 792 struct in_addr addr; 791 793 struct in_addr mask; 794 char *name; 792 795 int negative; 793 796 }; … … 818 821 mask_addr(&iaddr, mask, sizeof(iaddr)); 819 822 s = strdup(inet_ntoa(iaddr)); 820 debug("adding direct address entry: %s/%s\n", s, inet_ntoa(*mask)); 823 debug("adding direct addr entry: %s%s/%s\n", 824 negative? "!": "", s, inet_ntoa(*mask)); 821 825 free(s); 822 826 memcpy( &direct_addr_list[n_direct_addr_list].addr, … … 824 828 memcpy( &direct_addr_list[n_direct_addr_list].mask, 825 829 mask, sizeof(*mask)); 830 direct_addr_list[n_direct_addr_list].name = NULL; 826 831 direct_addr_list[n_direct_addr_list].negative = negative; 827 832 n_direct_addr_list++; 828 833 return 0; 829 834 } 835 836 837 /* add domain/host name entry to direct name table */ 838 int 839 add_direct_host( const char *name, int negative) 840 { 841 if ( MAX_DIRECT_ADDR_LIST <= n_direct_addr_list ) { 842 error("direct address table is full!\n"); 843 return -1; 844 } 845 if (*name == '*') 846 name++; 847 if (*name == '.') 848 name++; 849 debug("adding direct name entry: %s%s\n", negative? "!": "", name); 850 direct_addr_list[n_direct_addr_list].name = downcase(strdup(name)); 851 direct_addr_list[n_direct_addr_list].negative = negative; 852 n_direct_addr_list++; 853 return 0; 854 } 855 830 856 831 857 int … … 845 871 846 872 assert( str != NULL ); 847 debug("parsing address pair: '%s'\n", str);848 873 addr->s_addr = 0; 849 874 mask->s_addr = 0; … … 949 974 add_direct_addr( &addr, &mask, negative ); 950 975 } else { 951 error("invalid addr format in %s: %s\n", envkey, beg);976 add_direct_host( beg, negative ); 952 977 } 953 978 if ( next != NULL ) … … 966 991 967 992 int 968 is_direct_address (const struct sockaddr_in *addr) 969 { 970 int i; 971 struct in_addr saddr, iaddr; 972 973 saddr = addr->sin_addr; 993 is_direct_address (const struct in_addr addr) 994 { 995 int i, neg; 996 struct in_addr iaddr; 974 997 975 998 /* Note: assume IPV4 address !! */ 976 999 for (i=0; i<n_direct_addr_list; i++ ) { 977 iaddr = saddr; 1000 if (direct_addr_list[i].name != NULL) 1001 continue; /* it's name entry */ 1002 neg = direct_addr_list[i].negative; 1003 iaddr = addr; 978 1004 mask_addr( &iaddr, &direct_addr_list[i].mask, 979 1005 sizeof(struct in_addr)); 980 1006 if (cmp_addr(&iaddr, &direct_addr_list[i].addr, 981 1007 sizeof(struct in_addr)) == 0) { 982 if (direct_addr_list[i].negative) { 983 debug("negative match, addr to be SOCKSify: %s\n", 984 inet_ntoa(saddr)); 1008 char *a, *m; 1009 a = strdup(inet_ntoa(direct_addr_list[i].addr)); 1010 m = strdup(inet_ntoa(direct_addr_list[i].mask)); 1011 debug("match with: %s/%s%s\n", a, m, neg? " (negative)": ""); 1012 free(a); 1013 free(m); 1014 return !neg? 1: 0; 1015 } 1016 } 1017 debug("not matched, addr to be relayed: %s\n", inet_ntoa(addr)); 1018 return 0; /* not direct */ 1019 } 1020 1021 1022 /* check s1 is ends with s2. 1023 return 1 if exact match or domain part match. 1024 return 0 if s1 is shorter than s2 or partial match. 1025 For example, 1026 ends_with("bar.com", "bar.com") => 1 (exact match) 1027 ends_with("foo.bar.com", "bar.com") => 1 (domain match) 1028 ends_with("foo.beebar.com", "bar.com") => 0 (partial match) 1029 ends_with("bar", "bar.com") => 0 (shorter) 1030 */ 1031 domain_match(const char *s1, const char *s2) 1032 { 1033 int len1, len2; 1034 const char *tail1, *tail2; 1035 len1 = strlen(s1); 1036 len2 = strlen(s2); 1037 if (len1 < len2 || len1 == 0 || len2 == 0) 1038 return 0; /* not match */ 1039 tail1 = s1 + len1; 1040 tail2 = s2 + len2; 1041 while (0 < len1 && 0 < len2) { 1042 if (*--tail1 != *--tail2) 1043 break; /* not match */ 1044 len1--, len2--; 1045 } 1046 if (len2 != 0) 1047 return 0; /* not match */ 1048 /* Now exact match, domain match or partial match. 1049 Return true if exact or domain match. 1050 Or continue checking. */ 1051 if (tail1 == s1 || tail1[-1] == '.') 1052 return 1; /* match! */ 1053 return 0; /* not match */ 1054 } 1055 1056 /* Check given NAME is ends with one of 1057 registered direct name entry. 1058 Return 1 if matched, or 0. 1059 */ 1060 int 1061 is_direct_name (const char *name) 1062 { 1063 int len, i; 1064 const char *tail; 1065 debug("checking %s is for direct?\n", name); 1066 name = downcase(strdup(name)); 1067 len = strlen(name); 1068 if (len < 1) 1069 return 0; /* false */ 1070 tail = &name[len]; 1071 for (i=0; i<n_direct_addr_list; i++ ) { 1072 int dlen, neg; 1073 const char *dname; 1074 const char *n, *d; 1075 dname = direct_addr_list[i].name; 1076 if (dname == NULL) 1077 continue; /* it's addr/mask entry */ 1078 neg = direct_addr_list[i].negative; 1079 if (domain_match(name, dname)) { 1080 debug("match with: %s%s\n", dname, neg? " (negative)": ""); 1081 if (neg) { 985 1082 return 0; /* not direct */ 986 } 987 if (!direct_addr_list[i].negative) { 988 debug("positive match, addr to be direct: %s\n", 989 inet_ntoa(saddr)); 1083 } else { 990 1084 return 1; /* direct*/ 991 1085 } 992 1086 } 993 1087 } 994 debug("not matched, addr to be SOCKSified: %s\n", inet_ntoa(saddr)); 995 return 0; /* not direct */ 1088 return 0; /* not matched */ 1089 } 1090 1091 /* check to connect to HOST directyly? 1092 return 1 if to be direct, 0 for else. */ 1093 int 1094 check_direct(const char *host) 1095 { 1096 struct in_addr addr; 1097 addr.s_addr = inet_addr(host); 1098 if (addr.s_addr != INADDR_NONE) { 1099 /* case of IP address */ 1100 if (is_direct_address(addr)) { 1101 debug("%s is for direct.\n", host); 1102 return 1; /* true */ 1103 } 1104 } else { 1105 /* case of hostname */ 1106 if (is_direct_name(host)) { 1107 debug("%s is for direct.\n", host); 1108 return 1; /* true */ 1109 } 1110 } 1111 debug("%s is for not direct.\n", host); 1112 return 0; /* false */ 996 1113 } 997 1114 … … 1230 1347 debug ("No direct address are specified.\n"); 1231 1348 } else { 1232 int i; 1233 for ( i=0; i<n_direct_addr_list; i++ ) { 1234 char *s1, *s2; 1235 s1 = strdup(inet_ntoa(direct_addr_list[i].addr)); 1236 s2 = strdup(inet_ntoa(direct_addr_list[i].mask)); 1237 debug(" #%d: %c%s/%s\n", i, 1238 (direct_addr_list[i].negative)? '!': ' ', 1239 s1, s2); 1240 free(s1); 1241 free(s2); 1242 } 1349 debug ("%d direct address entries.\n", n_direct_addr_list); 1243 1350 } 1244 1351 … … 1601 1708 sig_timeout(void) 1602 1709 { 1603 debug( "timed out\n" );1604 1710 signal( SIGALRM, SIG_IGN ); 1605 1711 alarm( 0 ); 1712 error( "timed out\n" ); 1713 exit(1); 1606 1714 } 1607 1715 … … 1668 1776 struct sockaddr_in saddr; 1669 1777 1670 if ( relay_method == METHOD_DIRECT ) { 1671 host = dest_host; 1672 port = dest_port; 1673 } else if ((local_resolve (dest_host, &saddr) >= 0)&& 1674 (is_direct_address(&saddr))) { 1675 debug("%s is connected directly\n", dest_host); 1676 relay_method = METHOD_DIRECT; 1677 host = dest_host; 1678 port = dest_port; 1679 } else { 1680 host = relay_host; 1681 port = relay_port; 1682 } 1683 1778 /* resolve address of proxy or direct target */ 1684 1779 if (local_resolve (host, &saddr) < 0) { 1685 1780 error("can't resolve hostname: %s\n", host); … … 2791 2886 #endif /* not _WIN32 */ 2792 2887 2888 if (check_direct(dest_host)) 2889 relay_method = METHOD_DIRECT; 2793 2890 /* make connection */ 2794 2891 if ( relay_method == METHOD_DIRECT ) {
