Telnet chat server for Linux x86_64

Тема в разделе "WASM.BEGINNERS", создана пользователем Hacker, 16 июл 2023.

  1. Application

    Application Active Member

    Публикаций:
    1
    Регистрация:
    15 окт 2022
    Сообщения:
    110
    Даже ИИСУС не мучал себя так. Создание неблокирующего сокета и ожидание входящих соединений с использованием функции poll(). Вдруг поможет
    Код (Text):
    1. section .data
    2.     server equ 0
    3.     client equ 1
    4.     buffer equ 2
    5.     addr equ 3
    6.     addrLen equ 4
    7.     pollset equ 5
    8.     pollsetSize equ 6
    9.     k_maxClients equ 128
    10.  
    11. section .text
    12.     global _start
    13.  
    14. _start:
    15.     ; Создаём неблокирующий сокет, использующий протокол TCP
    16.     mov eax, 41
    17.     mov ebx, 1
    18.     mov ecx, 6
    19.     xor edx, edx
    20.     int 0x80
    21.     mov ebx, eax
    22.     mov eax, 102
    23.     xor ecx, ecx
    24.     xor edx, edx
    25.     mov esi, 65533
    26.     int 0x80
    27.  
    28.     ; Задаём сокету порт 65533
    29.     mov eax, 49
    30.     mov ebx, 1
    31.     xor ecx, ecx
    32.     mov dx, 65533
    33.     push ecx
    34.     push dx
    35.     push ebx
    36.     mov ecx, esp
    37.     mov edx, 16
    38.     int 0x80
    39.  
    40.     ; Создаём очередь входящих пакетов
    41.     mov eax, 50
    42.     mov ebx, 1
    43.     mov ecx, 512
    44.     int 0x80
    45.  
    46.     ; Резервируем список объектов для poll'a
    47.     mov dword [pollsetSize], 1
    48.  
    49. listen_loop:
    50.     ; Ждём бесконечно, пока один из объектов в поллсете не просигналит
    51.     mov eax, 52
    52.     mov ebx, [pollset]
    53.     mov ecx, [pollsetSize]
    54.     mov edx, -1
    55.     int 0x80
    56.  
    57.     ; Пройдёмся по всему поллсету и найдём того, кто просигналил
    58.     mov ebx, 0
    59.     mov esi, [pollsetSize]
    60.     mov edi, pollset
    61.  
    62. poll_loop:
    63.     cmp ebx, esi
    64.     jge listen_loop_end
    65.  
    66.     ; Смотрим, какой объект просигналил
    67.     mov eax, [edi + ebx * 8]
    68.     test byte [eax + 1], 1
    69.     jz poll_next
    70.  
    71.     ; Сбрасываем маску событий
    72.     mov byte [eax + 1], 0
    73.  
    74.     ; Обработка серверного сокета
    75.     cmp ebx, 0
    76.     jne client_data
    77.  
    78.     ; На сервер пришёл новый клиент, принимаем его
    79.     mov eax, 42
    80.     mov ebx, [server]
    81.     mov ecx, addr
    82.     mov edx, addrLen
    83.     int 0x80
    84.     mov ebx, eax
    85.  
    86.     cmp [pollsetSize], k_maxClients
    87.     jg client_disconnect
    88.  
    89.     ; Добавляем клиента в поллсет
    90.     mov eax, ebx
    91.     mov ebx, [pollsetSize]
    92.     mov edi, pollset
    93.     shl ebx, 3
    94.     add edi, ebx
    95.     mov [edi], eax
    96.     mov byte [edi + 1], 1
    97.     inc dword [pollsetSize]
    98.  
    99.     jmp poll_next
    100.  
    101. client_data:
    102.     ; Клиент прислал данные, читаем
    103.     mov eax, 45
    104.     mov ebx, [eax + ebx * 8]
    105.     mov ecx, buffer
    106.     mov edx, 65536
    107.     xor esi, esi
    108.     int 0x80
    109.  
    110.     ; ... Теперь у нас данные в buffer, можно с ними работать ...
    111.  
    112.     jmp poll_next
    113.  
    114. client_disconnect:
    115.     ; Мы упёрлись в лимит клиентов, отключаем клиента
    116.     mov eax, 6
    117.     mov ebx, [client]
    118.     xor ecx, ecx
    119.     int 0x80
    120.  
    121. poll_next:
    122.     inc ebx
    123.     jmp poll_loop
    124.  
    125. listen_loop_end:
    126.     ; Завершение программы
    127.     mov eax, 1
    128.     xor ebx, ebx
    129.     int 0x80
    130.  
    --- Сообщение объединено, 28 окт 2023 ---
    Код (Text):
    1. section .data
    2.     fds: resb 0
    3.     fds_len: dd 0
    4.     FDS_ARRAY_CHUNK_SIZE equ 100
    5.     MAX_MESSAGE_LEN equ 1728
    6.     do_linemode db 255, 253, 34
    7.     on_linemode db 255, 250, 34, 1, 1, 255, 240
    8.     will_echo db 255, 253, 1
    9.     wont_echo db 255, 252, 1
    10.     reply_buff db 512 dup(0)
    11.  
    12. section .text
    13.     global _start
    14.  
    15. _start:
    16.     ; Initialize fds and fds_len
    17.     mov eax, 0
    18.     mov fds_len, eax
    19.  
    20.     ; Set stdout to unbuffered mode
    21.     xor eax, eax
    22.     mov [stdout], eax
    23.  
    24.     ; Check if host and port are provided
    25.     cmp dword [argc], 3
    26.     jne error
    27.  
    28.     ; Create socket
    29.     xor eax, eax
    30.     xor ebx, ebx
    31.     xor ecx, ecx
    32.     mov al, 2
    33.     mov bl, 1
    34.     mov ecx, 0
    35.     int 0x80
    36.     mov servfd, eax
    37.  
    38.     ; Set server address
    39.     xor eax, eax
    40.     xor ebx, ebx
    41.     xor ecx, ecx
    42.     mov al, 2
    43.     mov bl, 1
    44.     mov ecx, 0
    45.     int 0x80
    46.     mov servaddr.sin_family, ax
    47.     mov servaddr.sin_addr.s_addr, ebx
    48.     mov servaddr.sin_port, cx
    49.  
    50.     ; Bind socket
    51.     xor eax, eax
    52.     xor ebx, ebx
    53.     xor ecx, ecx
    54.     mov al, 2
    55.     mov bl, 2
    56.     mov ecx, 0
    57.     int 0x80
    58.  
    59.     ; Listen for connections
    60.     xor eax, eax
    61.     xor ebx, ebx
    62.     xor ecx, ecx
    63.     mov al, 2
    64.     mov bl, 4
    65.     mov ecx, 1024
    66.     int 0x80
    67.  
    68.     ; Set socket to non-blocking mode
    69.     xor eax, eax
    70.     xor ebx, ebx
    71.     xor ecx, ecx
    72.     mov al, 54
    73.     mov bl, 2
    74.     mov ecx, 1
    75.     int 0x80
    76.  
    77.     ; Add server socket to fds
    78.     mov eax, servfd
    79.     call fds_set
    80.  
    81.     ; Start main loop
    82. main_loop:
    83.     ; Poll for events
    84.     xor eax, eax
    85.     xor ebx, ebx
    86.     xor ecx, ecx
    87.     mov al, 1
    88.     mov ebx, fds
    89.     mov ecx, fds_len
    90.     mov edx, 100
    91.     int 0x80
    92.     mov pollret, eax
    93.  
    94.     ; Process events
    95.     xor eax, eax
    96.     xor ebx, ebx
    97.     xor ecx, ecx
    98.     mov ecx, fds_len
    99.     mov ebx, fds
    100. process_events_loop:
    101.     cmp eax, ecx
    102.     jge main_loop_end
    103.  
    104.     ; Check if fd is valid
    105.     mov edx, [ebx + eax * 8]
    106.     cmp edx, 0
    107.     jle process_events_next
    108.  
    109.     ; Check if POLLIN event is set
    110.     mov edx, [ebx + eax * 8 + 4]
    111.     and edx, 1
    112.     jz process_events_next
    113.  
    114.     ; Check if fd is server socket
    115.     cmp edx, servfd
    116.     je process_events_accept
    117.  
    118.     ; Read message from client
    119.     xor eax, eax
    120.     xor ebx, ebx
    121.     xor ecx, ecx
    122.     mov al, 3
    123.     mov ebx, edx
    124.     mov ecx, buff
    125.     mov edx, MAX_MESSAGE_LEN
    126.     int 0x80
    127.  
    128.     ; Replace commands with spaces
    129.     xor eax, eax
    130.     xor ebx, ebx
    131.     xor ecx, ecx
    132.     mov ecx, eax
    133. replace_commands_loop:
    134.     cmp ecx, edx
    135.     jge process_events_send_to_all
    136.     mov bl, [ebx + ecx]
    137.     cmp bl, 0
    138.     je replace_commands_end
    139.     cmp bl, ' '
    140.     jl replace_commands_space
    141.     cmp bl, 126
    142.     jg replace_commands_space
    143.     jmp replace_commands_next
    144. replace_commands_space:
    145.     mov bl, ' '
    146. replace_commands_next:
    147.     mov [ebx + ecx], bl
    148.     inc ecx
    149.     jmp replace_commands_loop
    150. replace_commands_end:
    151.  
    152.     ; Send message to all clients
    153. process_events_send_to_all:
    154.     xor eax, eax
    155.     xor ebx, ebx
    156.     xor ecx, ecx
    157.     mov ecx, fds_len
    158.     mov ebx, fds
    159. send_to_all_loop:
    160.     cmp eax, ecx
    161.     jge process_events_next
    162.     mov edx, [ebx + eax * 8]
    163.     cmp edx, 0
    164.     jle send_to_all_next
    165.     cmp edx, servfd
    166.     je send_to_all_next
    167.     xor eax, eax
    168.     xor ebx, ebx
    169.     xor ecx, ecx
    170.     mov al, 4
    171.     mov ebx, edx
    172.     mov ecx, buff
    173.     mov edx, MAX_MESSAGE_LEN
    174.     int 0x80
    175. send_to_all_next:
    176.     inc eax
    177.     jmp send_to_all_loop
    178.  
    179.     ; Accept new connection
    180. process_events_accept:
    181.     xor eax, eax
    182.     xor ebx, ebx
    183.     xor ecx, ecx
    184.     mov al, 5
    185.     mov ebx, servfd
    186.     xor ecx, ecx
    187.     xor edx, edx
    188.     int 0x80
    189.     mov connfd, eax
    190.  
    191.     ; Perform telnet negotiation
    192.     xor eax, eax
    193.     xor ebx, ebx
    194.     xor ecx, ecx
    195.     mov al, 6
    196.     mov ebx, connfd
    197.     int 0x80
    198.  
    199.     ; Add new client to fds
    200.     mov eax, connfd
    201.     call fds_set
    202.  
    203. process_events_next:
    204.     inc eax
    205.     jmp process_events_loop
    206.  
    207. main_loop_end:
    208.     ; Exit program
    209.     xor eax, eax
    210.     xor ebx, ebx
    211.     xor ecx, ecx
    212.     int 0x80
    213.  
    214. error:
    215.     ; Print error message
    216.     xor eax, eax
    217.     xor ebx, ebx
    218.     xor ecx, ecx
    219.     mov al, 4
    220.     mov ebx, 1
    221.     mov ecx, error_message
    222.     mov edx, error_message_len
    223.     int 0x80
    224.  
    225.     ; Exit program
    226.     xor eax, eax
    227.     xor ebx, ebx
    228.     xor ecx, ecx
    229.     int 0x80
    230.  
    231. fds_set:
    232.     ; Add fd to fds
    233.     push ebp
    234.     mov ebp, esp
    235.     pushad
    236.  
    237.     mov eax, 0
    238.     mov ebx, fds_len
    239. fds_set_loop:
    240.     cmp eax, ebx
    241.     je fds_set_found
    242.     mov edx, [fds + eax * 8]
    243.     cmp edx, -1
    244.     jge fds_set_next
    245.     mov [fds + eax * 8], ebp
    246.     mov [fds + eax * 8 + 4], 1
    247.     jmp fds_set_end
    248. fds_set_next:
    249.     inc eax
    250.     jmp fds_set_loop
    251. fds_set_found:
    252.     call extend_fds
    253.     mov [fds + eax * 8], ebp
    254.     mov [fds + eax * 8 + 4], 1
    255. fds_set_end:
    256.     popad
    257.     pop ebp
    258.     ret
    259.  
    260. extend_fds:
    261.     ; Extend fds array
    262.     push ebp
    263.     mov ebp, esp
    264.     pushad
    265.  
    266.     mov eax, fds_len
    267.     add eax, FDS_ARRAY_CHUNK_SIZE
    268.     mov ebx, eax
    269.     mov eax, fds
    270.     push eax
    271.     push ebx
    272.     push 8
    273.     call realloc
    274.     add esp, 12
    275.  
    276.     xor eax, eax
    277.     mov ebx, FDS_ARRAY_CHUNK_SIZE
    278. extend_fds_loop:
    279.     cmp eax, ebx
    280.     je extend_fds_end
    281.     mov edx, [fds + fds_len * 8]
    282.     mov [edx], -1
    283.     mov [edx + 4], 0
    284.     inc eax
    285.     inc fds_len
    286.     jmp extend_fds_loop
    287. extend_fds_end:
    288.  
    289.     popad
    290.     pop ebp
    291.     ret
    292.  
    293. section .bss
    294.     stdout resb 4
    295.  
    296. section .data
    297.     error_message db "Please provide host and port. Example: telnet-chat 0.0.0.0 4022", 0
    298.     error_message_len equ $ - error_message
    299.  
     
    Последнее редактирование: 28 окт 2023
    Kulesh нравится это.
  2. Hacker

    Hacker Member

    Публикаций:
    0
    Регистрация:
    9 авг 2018
    Сообщения:
    170
    Адрес:
    Москва
    Спасибо что откликнулись! Но мне нужен читабельный код и x64, я буду выкладывать исходник сервера.
    С порядком вызовом функций ознакомлюсь, если получится
     
  3. HoShiMin

    HoShiMin Well-Known Member

    Публикаций:
    5
    Регистрация:
    17 дек 2016
    Сообщения:
    1.455
    Адрес:
    Россия, Нижний Новгород
    Ишь какой! Мы тебе напишем код, а ты его выложишь в паблик под своим авторством. А ловко ты это придумал!
     
    Mikl___ нравится это.
  4. Application

    Application Active Member

    Публикаций:
    1
    Регистрация:
    15 окт 2022
    Сообщения:
    110
    А с чего тебе давать читабельный код? В чем твоя ценность? )
     
    Последнее редактирование: 30 окт 2023
    Mikl___ нравится это.
  5. alex_dz

    alex_dz Active Member

    Публикаций:
    0
    Регистрация:
    26 июл 2006
    Сообщения:
    449
    2000$
     
    Mikl___ нравится это.
  6. Hacker

    Hacker Member

    Публикаций:
    0
    Регистрация:
    9 авг 2018
    Сообщения:
    170
    Адрес:
    Москва
    Можно спросить по коду? Почему MAX_MESSAGE_LEN equ 1728 и reply_buff db 512 dup(0) имеют разные значения?
     
  7. HoShiMin

    HoShiMin Well-Known Member

    Публикаций:
    5
    Регистрация:
    17 дек 2016
    Сообщения:
    1.455
    Адрес:
    Россия, Нижний Новгород
    Выглядит, будто эти значения взяты с потолка. В TCP размер пакета и на приём, и на передачу не может быть больше 65535 байт.
     
  8. alex_dz

    alex_dz Active Member

    Публикаций:
    0
    Регистрация:
    26 июл 2006
    Сообщения:
    449
    а как же джамбограма на 4же?
     
  9. MaKsIm

    MaKsIm Member

    Публикаций:
    0
    Регистрация:
    11 фев 2008
    Сообщения:
    96
    Вот мне интересно, если портов всего 65535 (0 - не считаем), тогда как в вашей схеме уместятся 100к клиентских сокетов, каждому из которых надо выделить свободный порт?
     
  10. mantissa

    mantissa Мембер Команда форума

    Публикаций:
    0
    Регистрация:
    9 сен 2022
    Сообщения:
    156
    зачем? все на один порт подключаются - серверный. для разных сервисов свои порты, днс, веб сервер и т.д.
     
  11. alex_dz

    alex_dz Active Member

    Публикаций:
    0
    Регистрация:
    26 июл 2006
    Сообщения:
    449
    Ваззапп делал 1М (1 миллион) TCP конектов еще 12 лет назад
    https://blog.whatsapp.com/1-million-is-so-2011
    --- Сообщение объединено, 4 ноя 2023 ---
    TCP (v4): 32 бита сорс, 32 бита дест адресс
    16 бит сорс 16 бит дест порт
    всего комбинаций 1 квадриллион https://prnt.sc/LdUgYNe67uIM
     
    mantissa нравится это.
  12. mantissa

    mantissa Мембер Команда форума

    Публикаций:
    0
    Регистрация:
    9 сен 2022
    Сообщения:
    156
    2277845 (2.2 М)
     
  13. MaKsIm

    MaKsIm Member

    Публикаций:
    0
    Регистрация:
    11 фев 2008
    Сообщения:
    96
    я говорил про getsockopt(..., SO_BSP_STATE, ...)
     
  14. HoShiMin

    HoShiMin Well-Known Member

    Публикаций:
    5
    Регистрация:
    17 дек 2016
    Сообщения:
    1.455
    Адрес:
    Россия, Нижний Новгород
    У принятых клиентов будет тот же локальный порт, что и у сервера, а remote-порты нас никак не ограничивают.
    Например, ты открыл порт :65533
    Локальный адресУдалённый адрес
    127.0.0.1:65533-Сервер
    127.0.0.1:65533111.111.111.111:1234Клиент 1
    127.0.0.1:65533222.222.222.222:5678Клиент 2
    У всех клиентов одинаковый локальный порт. Можешь убедиться в этом, например, в netstat.
     
  15. MaKsIm

    MaKsIm Member

    Публикаций:
    0
    Регистрация:
    11 фев 2008
    Сообщения:
    96
    Странно. У меня на Linux локальные порты разные и не повторяются. Больше 10000 соединений я открывать не пробовал, но сделал вывод, что они не должны повторяться (т.е. при превышении 65535 будет ошибка соединения). Пробовал только с TCP соединениями. Но возможно я что-то не настроил.

    На следующих выходных набросаю программу проверки и попробую открыть больше 70000 соединений с трех-пяти виртуальных машин.

    ADD: Кажется надо включать SO_REUSERADDR. Тогда адреса используют один и тот же номер порта.
     
    Последнее редактирование: 5 ноя 2023
  16. Hacker

    Hacker Member

    Публикаций:
    0
    Регистрация:
    9 авг 2018
    Сообщения:
    170
    Адрес:
    Москва
    Можете оставить свои копирайты информацию
    --- Сообщение объединено, 7 ноя 2023 ---
     
  17. HoShiMin

    HoShiMin Well-Known Member

    Публикаций:
    5
    Регистрация:
    17 дек 2016
    Сообщения:
    1.455
    Адрес:
    Россия, Нижний Новгород
    Hacker, а в каком месте в чат-сервере должен быть telnet? Может, ты имел в виду чат на TCP-сокетах?
     
  18. Hacker

    Hacker Member

    Публикаций:
    0
    Регистрация:
    9 авг 2018
    Сообщения:
    170
    Адрес:
    Москва
    telnet как клиент
    --- Сообщение объединено, 8 ноя 2023 ---
    Кому интересно присоединяйтесь к разработке на XRDP dchub.one
    [​IMG]
    [​IMG]
     
  19. HoShiMin

    HoShiMin Well-Known Member

    Публикаций:
    5
    Регистрация:
    17 дек 2016
    Сообщения:
    1.455
    Адрес:
    Россия, Нижний Новгород
    А как это должно работать?
    Телнет - это же протокол для доступа к терминалу. Чат по телнету - это вообще как? К какому терминалу он будет соединяться?
     
  20. Hacker

    Hacker Member

    Публикаций:
    0
    Регистрация:
    9 авг 2018
    Сообщения:
    170
    Адрес:
    Москва
    ну хз как тебе объяснить, тут лыжи скорей всего, обе две
    --- Сообщение объединено, 8 ноя 2023 ---
    Протакол будет ограничен функциями сервера, я думаю в Си коде этот момент есть