💾 Archived View for gmi.noulin.net › gitRepositories › spartserv › file › spartasm › main.asm.gmi captured on 2023-07-10 at 15:38:55. Gemini links have been rewritten to link to archived content

View Raw

More Information

-=-=-=-=-=-=-

spartserv

Log

Files

Refs

README

main.asm (6527B)

     1 %include "constants.asm"
     2 %include "macros.asm"
     3 
     4 ;Follwing amd64 syscall standards for internal function calls: rdi rsi rdx r10 r8 r9
     5 
     6 section .data
     7     %include "data.asm"
     8 
     9 section .bss
    10     listen_socket: resq 1
    11     listen_port: resw 1
    12     one_constant: resq 1
    13     directory_path: resq 1
    14 
    15 section .text
    16     %include "string.asm"
    17     %include "syscall.asm"
    18 
    19 global  _start
    20 
    21 _start:
    22 
    23     mov QWORD [one_constant], 1
    24 
    25     mov rdi, [rsp]    ;Num of args
    26     cmp rdi,3         ;Exit if no argument, should be directory location
    27     jne exit_with_help
    28 
    29     mov rdi, [rsp+16+8]; Port (second) parameter
    30     call string_atoi
    31     xchg al, ah
    32     mov [listen_port], eax
    33 
    34     mov rax, [rsp+16] ;Directory (first) parameter
    35     mov [directory_path], rax
    36 
    37     ;Try opening directory
    38     mov rdi, [directory_path]
    39     call sys_open_directory
    40 
    41     cmp rax, 0
    42     jl exit_with_no_directory_error
    43 
    44     ;Create socket
    45     call sys_create_tcp_socket
    46     cmp rax, 0
    47     jl exit_error
    48     mov [listen_socket], rax
    49 
    50     ;reuseaddr
    51     mov rdi, [listen_socket]
    52     call sys_reuse
    53 
    54     ;Bind to port
    55     call sys_bind_server
    56     cmp rax, 0
    57     jl exit_bind_error
    58 
    59     ;Start listening
    60     call sys_listen
    61 
    62     mov rbp, rsp
    63     sub rsp, 16
    64     ;Offsets: 8 - socket fd, 16 - buffer
    65 
    66     mov QWORD [rbp-16], 0 ; Used for pointer to recieve buffer
    67 
    68     mov rdi, BUFFER_SIZE+2+URL_LENGTH_LIMIT+DIRECTORY_LENGTH_LIMIT ; Allow room to append nul, and to create path
    69     call sys_mmap_mem
    70     mov QWORD [rbp-16], rax
    71 
    72 event_loop_start:
    73 
    74     call sys_accept
    75 
    76     mov [rbp-8], rax ; save fd
    77 
    78     mov rdi, rax
    79     call sys_cork ; cork it
    80 
    81     ;Network stuff starts here
    82     mov rdi, QWORD [rbp-8] ;fd
    83     mov rsi, [rbp-16]      ;buffer
    84     mov rdx, BUFFER_SIZE   ;size
    85     call sys_recv
    86 
    87     cmp rax, 0
    88     jle close_client_connection
    89 
    90     push rax ; save original received length
    91 
    92     ; add nul
    93     mov rdi, [rbp-16]
    94     add rdi, rax
    95     mov BYTE [rdi], 0x00
    96 
    97     ;Make sure its a valid request
    98     mov rdi, [rbp-16]
    99     mov rsi, crlf
   100     call string_ends_with
   101     cmp rax, 1
   102     jne invalid_request_response_pop_length
   103 
   104     ;Find request
   105     mov rax, 0x2F ; '/' character
   106     mov rdi, [rbp-16] ;scan buffer
   107     mov rcx, -1         ;Start count
   108     cld               ;Increment rdi
   109     repne scasb
   110     jne invalid_request_response_pop_length
   111     mov rax, -2
   112     sub rax, rcx      ;Get the length
   113 
   114     mov r8, rax ; start offset for requested file
   115     mov rdi, [rbp-16]
   116     add rdi, r8
   117     mov rax, 0x20  ;'space' character
   118     mov rcx, -1
   119     cld
   120     repne scasb
   121     jne invalid_request_response_pop_length
   122     mov rax, -1
   123     sub rax, rcx
   124     mov r9, rax
   125     add r9, r8  ;end offset
   126 
   127     ;TODO: Assuming it's a file, need directory handling too
   128 
   129     pop r11 ; restore orig recvd length
   130     mov rdi, [rbp-16]
   131     add rdi, r11 ; end of buffer, lets use it!
   132     mov r12, r11 ; keeping count
   133 
   134     mov rsi, [directory_path]
   135     xor r15, r15 ; Make sure directory path does not exceed DIRECTORY_LENGTH_LIMIT
   136 
   137 append_directory_path:
   138     inc r15
   139     cmp r15, DIRECTORY_LENGTH_LIMIT
   140     je invalid_request_response
   141     lodsb
   142     stosb
   143     inc r12
   144     cmp al, 0x00
   145     jne append_directory_path
   146 
   147     dec r12 ; get rid of 0x00
   148 
   149     ; Adds the file to the end of buffer ( where we just put the document prefix )
   150     mov rsi, [rbp-16]
   151     add rsi, r8  ; points to beginning of path
   152     mov rdi, [rbp-16]
   153     add rdi, r12 ;go to end of buffer
   154     mov rcx, r9
   155     sub rcx, r8
   156     cmp rcx, URL_LENGTH_LIMIT ; Make sure this does not exceed URL_PATH_LENGTH
   157     jg invalid_request_response
   158     add r12, rcx
   159     rep movsb
   160 
   161     dec r12 ; exclude space character
   162     mov rdi, [rbp-16]
   163     add rdi, r12
   164     mov BYTE [rdi], 0x00 ; add nul
   165 
   166     mov r9, r11 ; saving offset into a stack saved register
   167     ; [rbp-16] + r9 now holds string for file opening
   168 
   169     remove_pre_dir:
   170 
   171     ;-----Simple request logging
   172     ; mov rdi, msg_request_log
   173     ; mov rsi, msg_request_log_len
   174     ; call sys_write
   175     ; mov rdi, [rbp-16]
   176     ; add rdi, r9
   177     ; call get_string_length
   178     ; mov rsi, rax
   179     ; call print_line
   180     ;-----End Simple logging
   181 
   182     mov rdi, [rbp-16]
   183     add rdi, r9
   184     mov rsi, filter_prev_dir ; remove any '../'
   185     call string_remove
   186     cmp rax, 0
   187     jne remove_pre_dir
   188 
   189 
   190     ; TODO content types
   191     ; mov rdi, [rbp-16]
   192     ; add rdi, r9
   193     ; call detect_content_type
   194     ; mov r8, rax ;r8: Content Type
   195 
   196     ;------------response----------------
   197 
   198     ;Try to open requested file
   199     mov rdi, [rbp-16]
   200     add rdi, r9
   201     call sys_open
   202     cmp rax, 0
   203 
   204     jl invalid_request_response ;file not found
   205 
   206     ; Done with buffer offsets, put response and data into it starting at beg
   207     mov r10, rax ; r10: file fd
   208 
   209     ; we're good to go
   210 
   211     ;---------2 Response Start------------
   212 
   213     ; get file size
   214     mov rdi, r10 ; fd
   215     xor rsi, rsi
   216     mov rdx, LSEEK_END
   217     call sys_lseek
   218 
   219     ;rax - total filesize
   220     push rax
   221 
   222     ;Seek to beg of file
   223     mov rdi, r10 ; fd
   224     xor rsi, rsi
   225     mov rdx, LSEEK_SET
   226     call sys_lseek
   227 
   228     ; send response header
   229     mov rdi, [rbp-8] ; socket
   230     mov rsi, text_gemini_s
   231     mov rdx, text_gemini_s_len
   232     call sys_send
   233 
   234     cmp rax, 0
   235     jle close_file
   236 
   237     ; send file
   238     mov rdi, [rbp-8] ; socket
   239     mov rsi, r10 ; fd
   240     pop rdx ; file size
   241     call sys_sendfile
   242     jmp close_file
   243     ;---------2 Response End--------------
   244 
   245     ;---------4 Response Start------------
   246 invalid_request_response_pop_length:
   247     pop rsi
   248 
   249 invalid_request_response:
   250     mov rdi, [rbp-8] ; socket
   251     mov rsi, invalid_s
   252     mov rdx, invalid_s_len
   253     call sys_send
   254 
   255     jmp close_client_connection
   256     ;---------4 Response End--------------
   257 
   258  close_file:
   259     ;Uncork
   260     mov rdi, [rbp-8]
   261     call sys_uncork
   262 
   263     ;Close File
   264     mov rdi, r10
   265     call sys_close
   266 
   267     ;Close Socket
   268 close_client_connection:
   269     mov rdi, [rbp-8]
   270     call sys_close
   271 
   272     jmp event_loop_start
   273 
   274 exit_with_no_directory_error:
   275     mov rdi, msg_not_a_directory
   276     mov rsi, msg_not_a_directory_len
   277     call print_line
   278     jmp exit
   279 
   280 exit_with_help:
   281     mov rdi, msg_help
   282     mov rsi, msg_help_len
   283     call print_line
   284     jmp exit
   285 
   286 exit_error:
   287     mov rdi, msg_error
   288     mov rsi, msg_error_len
   289     call print_line
   290 
   291     mov rdi, -1
   292     mov rax, SYS_EXIT_GROUP
   293     syscall
   294     jmp exit
   295 
   296 exit_bind_error:
   297     mov rdi, msg_bind_error
   298     mov rsi, msg_bind_error_len
   299     call print_line
   300 
   301     mov rdi, -1
   302     mov rax, SYS_EXIT_GROUP
   303     syscall
   304     jmp exit
   305 
   306 exit:
   307 
   308     mov rdi, [listen_socket]
   309     call sys_close
   310 
   311     xor rdi, rdi
   312     mov rax, SYS_EXIT_GROUP
   313     syscall
   314