Сервер Telnet не запускается

Типичная ситуация Вы встречаетесь со строгими проблемами искажения, при накладывании структуры (как устройство/сетевое сообщение) на буфер размера слова системы (как указатель на uint32_t с или uint16_t с. Когда Вы накладываете структуру на такой буфер, или буфер на такую структуру через указатель, бросая Вас может легко нарушить строгие правила искажения.

Так в этом виде установки, если бы я хочу отправить сообщение во что-то, у меня должно было бы быть два несовместимых указателя, указывающие на тот же блок памяти. Я мог бы тогда наивно кодировать что-то вроде этого:

typedef struct Msg
{
    unsigned int a;
    unsigned int b;
} Msg;

void SendWord(uint32_t);

int main(void)
{
    // Get a 32-bit buffer from the system
    uint32_t* buff = malloc(sizeof(Msg));

    // Alias that buffer through message
    Msg* msg = (Msg*)(buff);

    // Send a bunch of messages    
    for (int i =0; i < 10; ++i)
    {
        msg->a = i;
        msg->b = i+1;
        SendWord(buff[0]);
        SendWord(buff[1]);   
    }
}

строгое правило искажения делает эту установку недопустимой: разыменование указателя, который искажает объект, который не имеет совместимый тип или один из других типов, позволенных к 2011 C 6,5 абзацев 7 1 глоток>, является неопределенным поведением. К сожалению, можно все еще кодировать этот путь, , возможно получают некоторые предупреждения, имеют его прекрасная компиляция, только для имения странного неожиданного поведения, когда Вы выполняете код.

(GCC кажется несколько непоследовательным в своей способности дать предупреждения искажения, иногда давая нам дружественное предупреждение и иногда нет.)

Для наблюдения, почему это поведение не определено мы должны думать о том, что строгое правило искажения покупает компилятор. В основном, с этим правилом, это не должно думать о вставке инструкций обновить содержание buff каждое выполнение цикла. Вместо этого при оптимизации, с некоторыми раздражающе добровольными предположениями об искажении, это может опустить те инструкции, загрузка buff[0] и buff[1] в ЦП регистрируется однажды, цикл выполняется, и ускорьте тело цикла. Прежде чем строгое искажение было представлено, компилятор должен был жить в состоянии паранойи, которую содержание buff могло изменить в любое время отовсюду кем-либо. Таким образом для получения дополнительного края производительности, и принимающий большинство людей не делают указателей игры слов типа, строгое правило искажения было представлено.

Имеют в виду, если Вы думаете, что пример изобретен, это могло бы даже произойти при передаче буфера другой функции, делающей посылание за Вами если вместо этого Вы имеете.

void SendMessage(uint32_t* buff, size_t size32)
{
    for (int i = 0; i < size32; ++i) 
    {
        SendWord(buff[i]);
    }
}

И переписал наш более ранний цикл для использования в своих интересах этой удобной функции

for (int i = 0; i < 10; ++i)
{
    msg->a = i;
    msg->b = i+1;
    SendMessage(buff, 2);
}

, компилятор может или не может быть в состоянии или достаточно умный, чтобы попытаться встроить SendMessage, и это может или не может решить загрузить или не загрузить любителя снова. Если SendMessage часть другого API, это компилируется отдельно, это, вероятно, имеет инструкции загрузить содержание любителя. С другой стороны возможно, Вы находитесь в C++, и это - некоторый шаблонный заголовок только реализация, что компилятор думает, что это может встроить. Или возможно это - просто что-то, что Вы записали в своем.c файле для Вашего собственного удобства. Так или иначе неопределенное поведение могло бы все еще последовать. Даже когда мы знаем часть из того, что происходит под капотом, это - все еще нарушение правила, таким образом, никакое четко определенное поведение не гарантируется. Таким образом, только путем обертывания в функции, которая берет наше слово, которому не обязательно помогает разграниченный буфер.

Поэтому, как я обхожу это?

  • Использование объединение. Большинство компиляторов поддерживает это, не жалуясь на строгое искажение. Это позволяется в C99 и явно позволяется в C11.

    union {
        Msg msg;
        unsigned int asBuffer[sizeof(Msg)/sizeof(unsigned int)];
    };
    
  • можно отключить строгое искажение в компиляторе ( f [нет-] строгое искажение в gcc))

  • , можно использовать char* для искажения вместо слова системы. Правила позволяют исключение для [1 112] (включая [1 113] и unsigned char). Всегда предполагается что char* псевдонимы другие типы. Однако это не будет работать другой путь: нет никакого предположения, что Ваша структура искажает буфер символов.

Новичок остерегается

, Это - только одно потенциальное минное поле при накладывании двух типов друг на друга. Необходимо также изучить [приблизительно 1 118] порядок байтов , выравнивание слов , и как заниматься проблемами выравнивания до [1 120] структуры упаковки правильно.

Сноска

1 глоток> типы, что 2011 C 6.5 7 позволяет lvalue доступу:

  • тип, совместимый с эффективным типом объекта,
  • квалифицированная версия типа, совместимого с эффективным типом объекта,
  • тип, который является или неподписанным типом со знаком, соответствующим эффективному типу объекта,
  • тип, который является или неподписанным типом со знаком, соответствующим квалифицированной версии эффективного типа объекта,
  • агрегат или тип объединения, который включает один из вышеупомянутых типов среди его участников (включая, рекурсивно, члена подсовокупного или содержавшего объединения), или
  • тип символов.

8
задан 17.05.2020, 19:44

1 ответ

После установки telnetd и xinetd с командой

sudo apt-get install xinetd telnetd

Создают файл telnet и вставляют /etc/xinetd.d

sudo nano /etc/xinetd.d/telnet

# default: on
# description: The telnet server serves telnet sessions; it uses
# unencrypted username/password pairs for authentication.
service telnet
{
disable = no
flags = REUSE
socket_type = stream
wait = no
user = root
server = /usr/sbin/in.telnetd
log_on_failure += USERID
}

Перезапуск xinetd сервис

sudo service xinetd restart

В xinetd.conf, Вы имеете includedir /etc/xinetd.d и не нуждаетесь в строке

telnet stream tcp nowait telnetd /usr/sbin/tcpd /usr/sbin/in.telnetd

стирание это.

В файле telnet можно добавить больше опции как:

only_from = 192.168.120.0/24 #Only users in 192.168.120.0 can access to
only_from = .bob.com #allow access from bob.com
no_access = 192.168.120.{101,105} #not allow access from the two IP.
2
ответ дан 17.05.2020, 19:44
  • 1
    Спасибо - это было повреждено в 14,10 / Надежный человек также. Создание файла и перезапуск сервисных работ. – Meligy 17.05.2020, 19:45

Теги

Похожие вопросы