Commits (3)
  • Rob Swindell's avatar
    Fix port parsing in dial string · 198ef67f
    Rob Swindell authored
    More case-insensitivity in parsing special "number" values (e.g. 'L' for last number).
    
    Default to Telnet mode (not Raw TCP).
    Default to unspecific address family (not IPv4).
    Case-insensitive "-telnet" and "-raw" option recognition.
    198ef67f
  • Rob Swindell's avatar
    Send a "banner" when accepting incoming connections. · d7b1f25e
    Rob Swindell authored
    Fix a corner case where an invalid command-mode escape sequence (e.g. "+.+.+") could've been interpreted as valid.
    d7b1f25e
  • Rob Swindell's avatar
    Resolve the socket protocol/address family issues with IPv4 vs. IPv6 · a6d7c580
    Rob Swindell authored
    When listening, the address family cannot be PF_UNSPEC, so default to PF_INET (IPv4), when not specified.
    Not sure why we're setting ai_flags to PF_UNSPEC (copied from syncterm) - that's just 0, but otherwise the PF_ and AI_ flags are not compatible.
    Don't set the ai_flags to anything here since they don't seem to change the behavior.
    a6d7c580
......@@ -75,6 +75,7 @@ struct {
ulong data_rate;
bool server_echo;
char busy_notice[INI_MAX_VALUE_LEN];
char answer_banner[INI_MAX_VALUE_LEN];
enum {
ADDRESS_FAMILY_UNSPEC
,ADDRESS_FAMILY_INET
......@@ -168,6 +169,8 @@ ulong count_esc(struct modem* modem, uint8_t* buf, size_t rd)
for(size_t i = 0; i < rd; i++) {
if(buf[i] == modem->esc)
count++;
else
return 0;
}
return count;
}
......@@ -353,13 +356,18 @@ const char* protocol(enum mode mode)
return "Raw";
}
int address_family()
int address_family(BOOL for_listen)
{
switch(cfg.address_family) {
case ADDRESS_FAMILY_INET: return PF_INET;
case ADDRESS_FAMILY_INET6: return PF_INET6;
}
return PF_UNSPEC;
return for_listen ? PF_INET : PF_UNSPEC;
}
int listen_address_family()
{
return address_family(true);
}
int putcom(char* buf, size_t len)
......@@ -574,24 +582,19 @@ char* dial(struct modem* modem, const char* number)
char* p = strrchr(host, ':');
char* b = strrchr(host, ']');
if(p != NULL && p > b) {
port = (uint16_t)strtol(p, &p, 10);
port = (uint16_t)strtol(p + 1, NULL, 10);
*p = 0;
}
dprintf("Connecting to port %hu at host '%s' via %s", port, host, protocol(mode));
memset(&hints, 0, sizeof(hints));
hints.ai_flags=PF_UNSPEC;
hints.ai_family=address_family();
hints.ai_family = address_family(/* for listen: */false);
hints.ai_socktype=SOCK_STREAM;
hints.ai_protocol=IPPROTO_TCP;
hints.ai_flags=AI_NUMERICSERV;
#ifdef AI_ADDRCONFIG
hints.ai_flags|=AI_ADDRCONFIG;
#endif
dprintf("%s %d calling getaddrinfo", __FILE__, __LINE__);
SAFEPRINTF(portnum, "%hu", port);
int result = getaddrinfo(host, portnum, &hints, &res);
if(result != 0) {
dprintf("getaddrinfo(%s, %s) returned %d", host, portnum, result);
dprintf("getaddrinfo(%s, %s) [family=%d] returned %d", host, portnum, hints.ai_family, result);
return response(modem, NO_ANSWER);
}
......@@ -699,6 +702,7 @@ char* answer(struct modem* modem)
/* Will suppress Go Ahead */
request_telnet_opt(TELNET_WILL,TELNET_SUP_GA);
}
putcom(cfg.answer_banner, strlen(cfg.answer_banner));
return connected(modem);
}
......@@ -725,13 +729,13 @@ char* atmodem_exec(struct modem* modem)
return error(modem);
if(*p == '=') {
p++;
if(strcmp(p, "L") == 0)
if(stricmp(p, "L") == 0)
p = modem->last;
SAFECOPY(modem->save[val], p);
return write_save(modem, val) ? ok(modem) : error(modem);
}
if(*p == '?' || strcmp(p, "L?") == 0) {
if(strcmp(p, "L?") == 0)
if(*p == '?' || stricmp(p, "L?") == 0) {
if(stricmp(p, "L?") == 0)
p = modem->last;
else
p = modem->save[val];
......@@ -1000,6 +1004,9 @@ bool read_ini(const char* ini_fname)
const char* p = iniGetString(ini, ROOT_SECTION, "BusyNotice", NULL, value);
if(p != NULL)
SAFECOPY(cfg.busy_notice, p);
p = iniGetString(ini, ROOT_SECTION, "AnswerBanner", NULL, value);
if(p != NULL)
SAFECOPY(cfg.answer_banner, p);
return true;
}
......@@ -1025,10 +1032,12 @@ int main(int argc, char** argv)
}
// Default configuration values
mode = TELNET;
cfg.server_echo = TRUE;
cfg.port = IPPORT_TELNET;
cfg.address_family = ADDRESS_FAMILY_INET;
cfg.address_family = ADDRESS_FAMILY_UNSPEC;
SAFECOPY(cfg.busy_notice, "\r\nSorry, not available right now\r\n");
SAFEPRINTF(cfg.answer_banner, "\r\n" TITLE " v" VERSION " Copyright %s Rob Swindell\r\n", &__DATE__[7]);
ini = strListInit();
GetModuleFileName(NULL, ini_fname, sizeof(ini_fname) - 1);
......@@ -1045,11 +1054,11 @@ int main(int argc, char** argv)
break;
while(*arg == '-')
arg++;
if(strcmp(arg, "telnet") == 0) {
if(stricmp(arg, "telnet") == 0) {
mode = TELNET;
continue;
}
if(strcmp(arg, "raw") == 0) {
if(stricmp(arg, "raw") == 0) {
mode = RAW;
continue;
}
......@@ -1064,7 +1073,7 @@ int main(int argc, char** argv)
cfg.listen = true;
arg++;
if(*arg != '\0') {
listening_interface.addr.sa_family = address_family();
listening_interface.addr.sa_family = listen_address_family();
if(inet_ptoaddr(arg, &listening_interface, sizeof(listening_interface)) == NULL) {
fprintf(stderr, "!Error parsing network address: %s", arg);
return EXIT_FAILURE;
......@@ -1114,13 +1123,13 @@ int main(int argc, char** argv)
if(sock != INVALID_SOCKET)
listening_sock = sock;
else {
listening_sock = socket(PF_INET, SOCK_STREAM, IPPROTO_IP);
listening_sock = socket(listen_address_family(), SOCK_STREAM, IPPROTO_IP);
if(listening_sock == INVALID_SOCKET) {
fprintf(stderr, "Error %ld creating socket\n", WSAGetLastError());
return EXIT_FAILURE;
}
}
listening_interface.addr.sa_family = address_family();
listening_interface.addr.sa_family = listen_address_family();
inet_setaddrport(&listening_interface, cfg.port);
result = bind(listening_sock, &listening_interface.addr, xp_sockaddr_len(&listening_interface));
if(result != 0) {
......@@ -1322,6 +1331,7 @@ int main(int argc, char** argv)
if(rd) {
if(modem.online) {
if(modem.esc_count) {
dprintf("Esc count = %d", modem.esc_count);
if(modem.esc_count >= 3)
modem.esc_count = 0;
else {
......@@ -1332,8 +1342,10 @@ int main(int argc, char** argv)
modem.esc_count = 0;
}
} else {
if(now - lasttx > guard_time(&modem))
if(now - lasttx > guard_time(&modem)) {
modem.esc_count = count_esc(&modem, buf, rd);
dprintf("New esc count = %d", modem.esc_count);
}
}
size_t len = rd;
uint8_t* p = buf;
......