About

I am Brendan Connelly, a computer engineering major at Clarkson University, expected to be graduating in May 2028. This semester, I'm taking Calc I, Physics I, and Chem I. Through running my website, I've learnt about a huge number of technologies in computer, software, and network engineering, such as:

Web Servers

You're looking at one of my first networking projects: this webpage itself. I'm running a LEMP stack to serve this website, which stands for Linux-NGINX (pronounced Egine-X)-MySQL-PHP. (I don't use MySQL anymore, but we can just ignore that for now :]). NGINX is the web server that I use, which manages web traffic and SSL encryption. MySQL is a relational database system which I used to use for KeebSocial Beta and for one of my first email tests. PHP is a system used for dynamically serving web content. In KeebSocial, I use it for authenticating logins and as the API language to interface with the database. On this main website, it's only real use is to add in the navbar onto each page so that I only need to keep it in one file.

Skills: HTML/CSS/JavaScript, PHP, Linux

SMTP

I set up a working email service, using Postfix as the mail agent, Dovecot to enable POP3 and IMAP4 support, RainLoop as a web client. My system fully worked with any TLS/SSL system, and complied to all DMARC, DKIM, and SPF specs. Although I am no longer maintaining this system (I can't exactly use it as most email services such as Gmail/Outlook send dynamic IP sources to spam automatically), it is still possible to sign up and use your account. Not all security features work any more, as I am not keeping up to date with any dynamic IP reallocations. In addition, it's a PAIN to get the SSL certificate to renew using LetsEncrypt's certbot, and I don't exactly remember how I rigged it to work in the first place. I'm currently not willing to purchase a static IP to use as a mail server, so KeebMail will slowly fall apart to time.

Skills: Linux, security

Robotics

For 3 years, I was the only programmer on the FIRST robotics team 4458. Being solely responsible for programming the robot taught me a lot about project organization, kinematics, and robotics in general (and how to tune out a crowd of people yelling at me while I'm typing). I think that the WPI branch on our 2024 repository is the best piece of software I've ever written. We were incredibly successful in 2024, and while we didn't make it to the world competition, we got very close, and I, along with everyone leading the team, owe most of the robot's success to the quality of the code I was able to produce for the robot. We used computer vision to automatically aim the robot using AprilTags, used a graphical interface to dynamically reprogram our autonomous routines, and established a "field-oriented" control scheme where our driver didn't even have to think about what way they were facing, which helped to make us dominant in competition.

Skills: Java, C++, kinematics

Virtualization

I don't exactly have any visual projects using virtualization (besides the future release of KeebSocial 2.0, but that's limited to containers), but in August I went into a deep dive into VM networking. I created my own isolated intranet essentially using VirtualBox copies of an Alpine Linux system. I manually set up routing tables, implemented NAT on dedicated router VMs, and ran a virtual DNS server, all to enhance my understanding of how the internet works. In the future, I'd like to expand upon this system, implementing BGP to automatically route new IP addresses which are added to the network.

Skills: Virtualization/Oracle VirtualBox/QEMU, Networking: TCP/IP, DNS, NAT, CIDR

Artificial Intelligence

I've only went into the very surface level of artificial intelligence, but it is an incredibly cool technology to play with. Years ago, I programmed a very basic evolutionary learning algorithm in Java FX to demonstrate how simple dots given a series of vectors can "learn" to make it through a maze. Somewhat more recently (2021?), I experimented with Markov chains, which are the basis of how LLMs and Generative AI systems work. I created a two-layer deep Markov chain system. It can't exactly do what ChatGPT can, but it's kind of fun to throw in song lyrics and watch it come up with a new verse.

A short output from the Markov chain program showing how it predicts the next word based on the last word (Only one layer deep because I couldn't think of a good way to visualize it two-layers deep over plaintext):
Word: there
Following words: [thats, thats]
Word: thats
Following words: [sleeping, sleeping]
Word: sleeping
Following words: [while, while]
Word: while
Following words: [my, my, my]
Word: my
Following words: [guitar, guitar, guitar, guitar, guitar, guitar]
Word: guitar
Following words: [gently, gently, gently, gently, gently, gently]
Word: gently
Following words: [weeps, weeps, weeps, weeps, weeps, weeps]
Word: weeps
Following words: [i, i, with, i, look, oh]
Word: i
Following words: [look, look, don't, don't, look, dont, dont, look]
Word: look
Following words: [at, at, at, at, at]
Word: at
Following words: [you, the, the, you, you]
Word: the
Following words: [love, floor, world, love]
Word: floor
Following words: [and]
Word: and



KeebSocial

KeebSocial is probably my most complete project yet (though it's still in the works.)

Skills: HTML, CSS, JavaScript, PHP, Docker, MongoDB

I already wrote a project description but it's on the repository and not on a web server so I'm just gonna... paste it here and hope it looks okay.


KeebSocial is project made as a tool to learn about full stack web development.

The source code is available on my GitHub.


Technical Overview

Docker

Docker is a piece of software which manages containers. Containers are, according to IBM (external link), executable units of software that package application code along with its libraries and dependencies. They allow code to run in any computing environment, whether it be desktop, traditional IT or cloud infrastructure. By containerizing applications, they can be made more portable, reliable, and secure. To spin up the entire project, just one command needs to be run. In addition, the container environment isolates each piece of software, so they can only communicate over known protocols. This way, if there is a breach in the web server, which is the only part of the package that is exposed to the internet, a hacker can't do anything else except mess with the networking setup. The only thing the hacker can do is ask PHP to serve a dynamic webpage. If NGINX and PHP or NGINX and the database were running in the same container, a breach to one would be a breach to all.

The project is made up of three separate Docker containers:

NGINX Container

NGINX is a free and open source web server software which has been gaining increasing market share over Apache, the industry standard, in recent years. NGINX is responsible for handling any web requests you send, manages SSL certificates, and forwards requests to other containers when need be.

PHP Container

The PHP container runs dynamic webpages in a separate container than they are served, which helps to increase the security of the entire stack. PHP serves as an interface between the HTML and the backend database. I have a series of API functions which can serve every single aspect of the platform. For example, there is a file to log in and get a session token, a file to get profile fields, and a file to get the content of a post, among many others.

MongoDB Container

Everything on that platform is ultimately stored in a database called MongoDB. MongoDB is a non-relational database, meaning that it exists outside the paradigm of tables and columns. I've structured every object on the platform to follow a few simple formats, which have been carefully thought out to minimize the amount of reads that have to be conducted. While I am sacrificing to an extent storage size to fit my format, it enables the platform to be far more scalable than a traditional relational database system. For example, likes are stored twice: once as a list of all users who liked the post, and once as a list of all posts liked by a user. This represents two distinct actions that may be done, optimizing the read time for both of them. On social media platforms, reads are going to far outnumber writes, so I think this optimization saves a significant number of computing power.


API Standard

I've written a bit of a standard for myself to help implement the API, which is below.

keebsocial/api/v1/AUTHORIZE.php
    user=username
    key=authentication token

    returns 0|1

keebsocial/api/v1/ACT.php
    key=authentication token
    type=POST|REPLY|REKEEB|LIKE
    content=UUID of the item to act on

    returns 0|1

keebsocial/api/v1/FOLLOW.php
    key=authentication token
    target=username to act on
    
    return 0|1|2, SUCCESS|FAILURE|REQUEST

keebsocial/api/v1/ACCEPT.php?user=user&key=key&target=target
    key=authentication token
    target=username to accept follow from
    returns 0|1

keebsocial/api/v1/GETKEEB.php
    key=authentication token
    content=uuid of keeb
    returns 0|1, text

keebsocial/api/v1/GETPROFILE.php
    key=authentication token
    target=username

    returns 0|1, username, bio, follows, followers

keebsocial/api/v1/SETPROFILE.php
    key=authentication token
    target=bio|
    content=what to set as
    

keebsocial/api/v1/GETPROFILEKEEBS.php
    key=authentication token
    target=username
    start=index of start
    end=index of end
    count=total number (if set, ignores start/end, reads from most recent)

    returns 0|1, uuids of all keebs by a user within bounds

keebsocial/api/v1/GETIMAGE.php
    key=authentication token
    content=image uuid

    returns 0|1, image if they have approval to view the parent keeb (the keeb in which the image is embedded)

keebsocial/api/v1/GETTIMELINE.php
    key=authentication token
    count=keeb count

    returns 0|1, most recent POST, REPLY, REKEEB keebs from those whom the calling user follows

keebsocial/api/v1/LOGIN.php
    user=username
    password=password
    returns 0|1, auth key

keebsocial/api/v1/LOGOUT.php
    user=username
    key=authentication token
    returns 0|1

keebsocial/api/v1/REGISTER.php
    user=username
    password=password
    returns 0|1

keebsocial/api/v1/PASSWD.php
    user=username
    old=old password
    new=new password
    returns 0|1

keebsocial/api/v2/GETNOTIFICATIONS.php
    key=authentication token

    returns 0|1, notifications

Database Objects

In addition, I've written out in plaintext a format for implementing the database:

Password Database
    users
        username
        email
        hash
        tokens
            token
            expiration

Content Databse
    users
        username
        name
        UUID
        date
        bio
        keebs
            [UUID...]
        followers
            [UUID...]
        follows
            [UUID...]
        likes
            [UUID...]
        keebs_count
        followers_count
        follows_count
        likes_count
    keebs
        UUID
        date
        content
        likes
            [UUID...]
        rekeebs
            [UUID...]
        likes_counts
        rekeebs_count
    media
        Media UUID
        Association UUID
        date